Windows Phone 7 开发探索笔记8——加载XAML文件中的对象

    上篇文章介绍了如何在Silverlight for Windows Phone中读取XML文件,本文来看一下如何从XAML文件中读取信息。

一.准备XAML文件

    有时候我们需要加载一些来自文件,资源中的UI元素,例如保存在XAML文件中的UI元素。首先来准备一个待读取的XAML文件,我们可以通过创建一个文本文件并将其扩展名改为.xaml的方式来创建,但更好的方式是在Visual Studio中创建,方法如下:右击解决方案资源管理器中的项目选择添加新项,选择任意一个扩展名为.xaml的项均可,然后将自动生成的内容清空,添加如下的代码:

Ellipse.xaml文件中的XAML代码:

代码
<Ellipse xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
         xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml" 
         VerticalAlignment
="Center" 
         HorizontalAlignment
="Center" 
         Height
="350" Width="350" >
    
<Ellipse.Fill>
        
<RadialGradientBrush  GradientOrigin="0.4,0.4" Center="0.4 0.4">
            
<GradientStop Color="White" Offset="0"/>
            
<GradientStop Color="Blue" Offset="1"/>
        
</RadialGradientBrush>
    
</Ellipse.Fill>
</Ellipse>

Rectangle.xaml文件中的XAML代码:

代码
<Rectangle xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
         xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml" 
         VerticalAlignment
="Center" 
         HorizontalAlignment
="Center"
           Height
="300" Width="350">
    
<Rectangle.Fill>
        
<LinearGradientBrush StartPoint="0 0.5" EndPoint="1 0.5">
            
<GradientStop Color="Azure" Offset="0"/>
            
<GradientStop Color="Red" Offset="0.5"/>
            
<GradientStop Color="Orange" Offset="1"/>
        
</LinearGradientBrush  >
    
</Rectangle.Fill>
</Rectangle>

我分别创建了两个XAML文件,其中一个是圆形,一个是矩形,设置好它们相应的属性即可,注意要添加相应的xml名称空间(xmlns)。在Visual Studio中创建的好处是可以得到设计器的帮助,看到实时的效果,当然也可以使用Expression Blend来做。最后,要注意把Visual Studio自动创建的Code-Behind文件删掉。

二.解析XAML文件

    要解析XAML文件中的信息,需要借助于XamlReader类,它为分析XAML和创建相应的Silverlight对象树提供XAML处理器引擎。在Silverlight for Windows Phone中它只包含一个静态的Load方法,此方法用来分析一段格式良好的XAML片段并创建相应的Silverlight对象树,然后返回这个对象树的根。Load方法接受一个string类型的参数,我们可以将XAML文件中的代码直接传给它,不过在实际项目中,通常不会硬编码,所以采用与上篇文章中相同的方法,Application类的GetResourceStream方法,代码如下:

代码
        T LoadXAMLAndGetShape<T>(string url)
        {
            
string xaml = string.Empty;
            StreamResourceInfo sri 
= Application.GetResourceStream(new Uri(url, UriKind.Relative));
            
using (StreamReader sr = new StreamReader(sri.Stream))
            {
                xaml 
= sr.ReadToEnd();
            }
            T shape 
= (T)XamlReader.Load(xaml);
            
return shape;
        }

这里我创建了一个泛型方法,以便返回不同类型的对象。在方法中,通过Application.GetResourceStream方法加载XAML文件,然后用StreamReader将它读成字符串,最后将字符串传入XamlReader的Load方法来构造相应的类型。

三.使用读取到的Silverlight对象

读取到相应的对象后就可以进行自由的操作了,我在程序中添加了2个按钮用来在页面中呈现两个不同的对象,完整代码如下:

代码
using System;
using System.IO;
using System.Windows;
using System.Windows.Markup;
using System.Windows.Resources;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;

namespace WindowsPhoneLoadXAML
{
    
public partial class MainPage : PhoneApplicationPage
    {
        Ellipse ellipse;

        Rectangle rectangle;

        
// Constructor
        public MainPage()
        {
            InitializeComponent();

            ellipse 
= LoadXAMLAndGetShape<Ellipse>("/WindowsPhoneLoadXAML;component/Ellipse.xaml");

            rectangle 
= LoadXAMLAndGetShape<Rectangle>("/WindowsPhoneLoadXAML;component/Rectangle.xaml");
        }

        T LoadXAMLAndGetShape
<T>(string url)
        {
            
string xaml = string.Empty;

            StreamResourceInfo sri 
= Application.GetResourceStream(new Uri(url, UriKind.Relative));

            
using (StreamReader sr = new StreamReader(sri.Stream))
            {
                xaml 
= sr.ReadToEnd();
            }

            T shape 
= (T)XamlReader.Load(xaml);

            
return shape;
        }

        
private void btnEllipse_Click(object sender, RoutedEventArgs e)
        {
            
if (ContentPanel.Children.Contains(rectangle))
            {
                
this.ContentPanel.Children.Remove(rectangle);
            }
            
if (ellipse != null && !ContentPanel.Children.Contains(ellipse))
            {
                
this.ContentPanel.Children.Add(ellipse);
            }
        }

        
private void btnRectangle_Click(object sender, RoutedEventArgs e)
        {
            
if (ContentPanel.Children.Contains(ellipse))
            {
                
this.ContentPanel.Children.Remove(ellipse);
            }
            
if (rectangle != null && !ContentPanel.Children.Contains(rectangle))
            {
                
this.ContentPanel.Children.Add(rectangle);
            }
        }
    }
}

下面是程序截图:

clip_image002clip_image004

四.下载示例代码:

WindowsPhoneLoadXAML.zip

如果大家喜欢我的文章,请点击“推荐”,谢谢!

posted @ 2010-12-10 11:24  YinBa  阅读(2291)  评论(6编辑  收藏  举报