WPF入门XAML详解
XAML
XAML(Extensible Applications Markup Language)用于实例化.net对象的标记语言。
创建一个WPF应用程序,生成的基本框架如下:
<Window x:Class="_001XAML.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:_001XAML"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
</Grid>
</Window>
这个文档只包含两个元素——顶级的Window元素和Grid元素,Window元素代表整个窗口,Grid元素中可以放置所有控件。WPF应用程序只使用使用以下几个元素作为顶级元素:
- Window元素
- Page元素(该元素和Window元素类似,但是它用于导航的应用程序)
- Application元素(该元素定义应用程序和启动设置)
XAM文档中只能有一个顶级元素。
Title="MainWindow" Height="450" Width="800"
Title
属性定义了应用程序的标题,Height
属性定义了窗体的高度,Width
属性定义了窗体的宽度。
XAML名称空间
xmlns
特性是XML中的一个特殊的特性,它专门用于声明名称空间。在创建的WPF XAML文档中都会使用这两个名称空间:
-
http://schemas.microsoft.com/winfx/2006/xaml/presentation
是WPF核心名称空间。包含了所有的WPF类,包括用于构建用户界面的控件。 -
http://schemas.microsoft.com/winfx/2006/xaml
是XAML名称空间。它包含各种XAML实用特性,这个命名空间被映射为前缀x,可用通过在元素名称之前放置一个名称空间前缀来使用这个名称空间(例如:x:ElementName)
代码隐藏类
通过XAML构造用户界面,通过代码隐藏类连接包含应用程序的事件处理程序的方法。
<Window x:Class="_001XAML.MainWindow"
Class特性告诉XAML解析器使用指定的名称生成一个新类。该类继承自由XML元素命名的类。换句话说,这个示例创建了一个MainWindow的新类,该类继承自Window这个基类。
namespace _001XAML
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}
当编译应用程序时,定义用户界面的XAML(如这里的MainWindow.xaml)被转换为CLR类型声明,和代码隐藏类文件(如MainWindow.xaml.cs)中的逻辑代码融合到一起,形成单一的单元。
- InitializeComponent()方法
在生成的MainWindow类中,默认的构造函数会调用InitializeComponent()
方法。该方法在源代码中是不可见的,这是在编译应用程序时自动生成的。该方法本质是调用了System.Windoes.Application
类的LoadComponent()
方法。
- 命名元素
如果要通过代码来操作控件,控件必须包含XAML.Name属性。比如要操作Grid控件,可以添加名称:
<Grid x:Name="grid1">
</Grid>
XAML中的属性和事件
简单属性
给一个文本框设置属性,设置对齐方式、设置页边距和字体。
<TextBox Name="txtAnswer"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
FontFamily="Times New Roman" FontSize="24" Foreground="Green"
>
...
</TextBox>
复杂属性
有些属性是一个对象,对象本身有自己一系列的属性。属性元素语法(property-element syntax),可以添加一个名称形式为Parent.PropertyName
的子元素。比如给Grid控件的Background属性添加绘制背景区域的画刷,可以添加名为Grid.Background的子标签。
<Grid>
<Grid.Background>
<LinearGradientBrush>
<LinearGradientBrush.GradientStops>
<GradientStop Offset="0.00" Color="Red"/>
<GradientStop Offset="0.50" Color="Indigo"/>
<GradientStop Offset="0.10" Color="Violet"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Grid.Background>
</Grid>
效果如下:
任何XAML标签集合都可以使用一系列执行相同任务的代码语句代替。
标记扩展
如果要将属性值设置为一个已经存在的对象,或者是希望通过一个属性绑定到另一个控件来动态地设置属性值。就需要使用标记扩展。
标记扩展可以用于嵌套标签或XAML特性中,当用于特性中,总是被花括号{}包起来使用。
<Button Name="button" Width="100" Height="50" Content="Button" Background="{x:Static SystemColors.ActiveCaptionBrush}"></Button>
这段XAML的最终结果和下面的一样:
button.Background = SystemColors.ActiveCaptionBrush;
因为标记扩展映射为类,所以他们也可以被用作嵌套属性:
<Button Width="100" Height="50" Content="Button">
<Button.Background>
<x:Static Member="SystemColors.ActiveCaptionBrush"></x:Static>
</Button.Background>
</Button>
标记扩展在使用资源和数据绑定时会大量用到。
附加属性
附加属性(attached property)用于多个控件在另一个类中定义的属性。附加属性常用于控件布局。
事件
特性也可以用于关联事件处理程序,用于关联事件处理程序的语法为:事件名="事件处理程序方法名"。
比如,Button控件提供一个Click事件:
<Button Name="button" Click="button_Click"></Button>
上述标记在代码隐藏类中必须对应的事件处理方法。
private void button_Click(object sender, RoutedEventArgs e)
{
// do something
}
使用其他名称空间中的类型
为使用未在WPF名称空间中定义的类,需要把.NET名称空间映射到一个XML名称空间。XAML有一个特殊的语法完成这项工作:
xmlns:Prefix="clr-namespace:Namespace;assembly=AssemblyName"
通常再XAML的根元素中,在紧跟WPF和XAML名称空间特性之后,放置这个名称空间。
-
Prefix用于指示名称空间的XML前缀
-
Namespace是完全限定的.NET名称空间的名称
-
AssemblyName是声明类型的程序集
比如,如何访问System名称空间中的基本类型,并把它们映射为前缀sys:
xmlns:sys="clr-namespace:Systemlassembly=mscorlib"
访问当前项目在MyProject名称空间中声明的类型,并把它们映射为前缀local:
xmlns:local="clr-namespqce:MyNamespace"
小案例: