XAML 和程序代码的混合
WPF 应用程序可以完全由任何 .NET 语言编写而 成,简单的应用程序也可以完全由 XAML 写成,但大多数 WPF 应用程序则是由 XAML 和程序代码混合而成的。
在运行时加载和解析 XAML
System.Windows.Markup 命名空间中的 XamlReader 和 XamlWriter 分别用于读取 XAML 和写入 XAML 。 XamlReader 定义了一些重载的静态方 法 Load , XamlWriter 定义一些重载的静态方法 Save 。
XamlReader
XamlReader.Load 方法用于解析 XAML 文件、创建合 适的 .NET 对象以及返回根元素的实例。假设当前目录包含 XAML 文件 MyWindow.xaml ,则可以通过下例 方法加载并取得 Window 对象:
Window window = null ;
using ( FileStream fs =
new FileStream ( "MyWindow.xaml" , FileMode .Open, FileAccess .Read))
{
// 获得根元素 Window
Window win = ( Window )XamlReader.Load(fs);
}
XamlReader 类还定义了 LoadAsync 实 例方法用以异步加载 XAML 文件。在加载较大文件或通过网络加载时,为了用户界面能够及时响应,则可以考虑使用异步模型。
假设 Window 拥有一个 StackPanel 类型的子元素,且该子元素的第 5 个子元素为 OK 按钮,则下面示例可以获得它们的引用(接上例):
StackPanel panel = ( StackPanel )window.Content;
Button okButton = ( Button )panel.Children[4];
此后就可以使用 Button 的引用来 完成一些 XAML 做不到的事情,比如调用按钮类的某个方法、设置额外的属性或者附加事件处理器等。
为 XAML 元素命名
XAML 语言命名空间中包含一个 Name 关键字,它用来设置元素的名称,如下( 该用法实际上有误,因为 x:Name 需和 x:Class 一同使用,此处仅为示意 ):
< Button x:Name = " okButton " > OK </ Button >
改动之后对应的 C# 代码将会更一般 化,如下:
Button okButoon = ( Button )window.FindName( "okButton" );
FindWindow 方法并不是 Window 类的方 法,它定义在 FrameworkElement 和 FrameworkContentElement 类中。这两个类都是 WPF 中非常重要的类。
x:Name 可以用来命名元素,但是某些类定义了可以被当作元素名称的属性(通过添加 System.Windows.Markup.RuntimeNamePropertyAttribute 实现),如 FrameworkElement 和 FrameworkContentElement 中都有 Name 属性,它们被标记为 RuntimeNameProperty(“Name”) 。这说明我们在这种元素上可以简单地通过设置 Name 属性来为其设置名称,而无需使用 x:Name 。我们 可以在这两种方法中选择一种使用,但不可两种都用。 XAML 提供这种机制的目的是为了在程序代码 中可以方便地使用 Name 属性,否则将不得不在 XAML 文件中同时设 置 Name 和 x:Name 的值。
(这里的所说的为 XAML 元素命名实际上包含两重含义。第一重是说, 通过某些元素的 Name 属性或通过 x:Name 关键字,可以为元素指定一个名称。这个名称被 看做一个 key 值,可以通过 FrameworkElement 的 FindName 方法获得相应的 value 值,该值即为那个元素的引用。第二重是说, 如果在 VS 中使用 code-behind 文件和分部类, VS 将会自动创建一个该元素类型的变量,且这个 变量的名称与该元素的名称相同。如上例, Button 的 Name 属性值为 okButton ,则在分部类中,可以直接通过名为 okButton 的变量引用该按钮对象。此外,对于那些标记 了 RuntimeNameProperty(“Name”) 的类型,无论是通过 Name 属性还是 x:Name 关键字设置的 XAML 元素名称,在程序代码中都可以通过 Name 属性获得,如下例:
XAML
< Window xmlns = " http://schemas.microsoft.com/winfx/2006/xaml/presentation "
xmlns:x = " http://schemas.microsoft.com/winfx/2006/xaml "
x:Class = " MyWindow " >
< Button Content = " OK " x:Name = " okButton " />
</ Window >
C#
public partial class Window1 : System.Windows. Window
{
public Window1()
{
InitializeComponent();
System.Diagnostics. Debug .WriteLine( this .okButton.Name );
}
}
调试运行程序,将会看到调试控制台显示 “okButton” 。)