19章XAML
松散XAML:
<Buttonxmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
Hello World!
</Button>
.xaml扩展名被关联到PresentationHost.exe程序。只要执行XAML,就会运行此程序,由其建立Page类型的对象,而此程序又可以嵌入IE中。PresentationHost.exe程序还将加载的XAML转成实际的Button对象,并将对象设定为Page的Content属性。
这里,是XamlReader.Load这个静态方法将XAML转成对象。
需要在服务器上为.xaml扩展名注册MIME类型,在.hta文件中加入下面这行:
AddType application/xaml+xml xaml
松散XAML的根元素可以是继承FrameworkElement的任何类,但不可以是Window。
XamlWriter.Save方法,从对象产生XAML——与XamlReader.Load功能正好相反。
使用XamlReader.Load手动加载XAML的方法:
stringstrXaml =
@"<Button xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
Foreground='LightSeaGreen' FontSize='24pt'>
Click me!
</Button>";
有两种加载方法:
方法1,操作内存:
MemoryStreammemory =newMemoryStream(strXaml.Length);
StreamWriterwriter =newStreamWriter(memory);
writer.Write(strXaml);
writer.Flush();
memory.Seek(0,SeekOrigin.Begin);
Objectbj =XamlReader.Load(memory);
方法2,作为XML读取:
StringReaderstrReader =newStringReader(strXaml);
XmlTextReaderxmlReader =newXmlTextReader(strReader);
Objectbj =XamlReader.Load(xmlReader);
将这个obj设置给Content,然后在Main中加载,完整代码如下:
publicclassLoadEmbeddedXaml:Window
{
[STAThread]
publicstaticvoidMain()
{
Applicationapp =newApplication();
app.Run(newLoadEmbeddedXaml());
}
publicLoadEmbeddedXaml()
{
stringstrXaml =
"<Button xmlns='http://schemas.microsoft.com/"+
"winfx/2006/xaml/presentation'"+
" Foreground='LightSeaGreen' FontSize='24pt'>"+
" Click me!"+
"</Button>";
StringReader strreader =newStringReader(strXaml);
XmlTextReader xmlreader =newXmlTextReader(strreader);
objectbj = XamlReader.Load(xmlreader);
Content = obj;
}
}
注意:加载XAML的内部过程:
PresentationHost.exe程序判断出返回对象为Button,于是进行相应转换
Buttonbtn = (Button)XamlReader.Load(xmlReader);
然后自动设置事件处理函数:
btn.Click += ButtonClick;
以上处理的是内嵌XAML——将其写入字符串中。下面是如何加载外部XAML:
这里,即使是一个xml文件,只要里面的内容是XAML的,也可以解析。
对于外部的LoadXamlResource.xml文件——位于与解决方案相同的目录下,在类的构造函数中对其进行加载:
Uriuri =newUri("pack://application:,,,/LoadXamlResource.xml");
Streamstream =Application.GetResourceStream(uri).Stream;
FrameworkElementel =XamlReader.Load(stream)asFrameworkElement;
Content = el;
Buttonbtn = el.FindName("MyButton")asButton;
if(btn !=null)
btn.Click += ButtonOnClick;
然后在Main函数中,运行这个实例:
publicstaticvoidMain()
{
Applicationapp =newApplication();
app.Run(newLoadXamlResource());
}
如果XAML是一个Window根元素,此时加载要特殊处理——直接在Main函数中处理,将加载到的流转型Window类型,并添加事件句柄,然后直接运行:
publicstaticvoidMain()
{
Applicationapp =newApplication();
Uriuri =newUri("pack://application:,,,/LoadXamlWindow.xml");
Stream stream =Application.GetResourceStream(uri).Stream;
Windowwin = XamlReader.Load(stream)asWindow;
win.AddHandler(Button.ClickEvent,
newRoutedEventHandler(ButtonOnClick));
app.Run(win);
}
对于使用Open File的方式打开磁盘上一个XAML:
XmlTextReaderxmlreader =newXmlTextReader(dlg.FileName);
// Convert XAML to object.
objectbj =XamlReader.Load(xmlreader);
// If it's a Window, call Show.
if(objisWindow)
{
Windowwin = objasWindow;
win.Owner =this;
win.Show();
}
// Otherwise, set as Content of Frame.
else
frame.Content = obj;
额外需要注意的是,对于一个Window对象的XAML,要把Owner设置为this自己。
xmln声明默认的XML默认命名空间。这个命名空间会被应用于声明出现的element以及其下的每个孩子。它的名称必须是唯一且一致的,所以常使用URL作为命名空间,也就是
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
XAML不只用于WPF,还可以用于WF等框架,所以这里使用presentation作为URL的后缀。
XAML规范定义了多个元素和属性,可以在任何XAML中使用,包括WPF。这些元素和属性被关联到不同于WPF的命名空间。由于我们肯定要使用到这些元素,所以要声明
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
这里标志为xmlns:x,从而XAML中的专用元素和属性都以x为前缀,例如x:Code和x:Class,它们都属于XAML命名空间,而非WPF命名空间。
由于WPF命名空间的元素和属性多于XAML命名空间,所以使用前者作为默认命名空间。
x:Class属性
只能出现在XAML文件的根元素中?