转载请注明出处
现在您大概了解了Silverlight是什么,Silverlight适用于哪些技术领域。您也安装了用于开发Silverlight应用程序所必须的工具软件。因此,现在是时候向前迈进了。本章将开始讲解可扩展应用程序标记语言(XAML)并且探索许多关于XAML的特性,如新的属性和事件来支持数据绑定,动画和其他Silverlight的关键部分。本章将花更多的注意力在Silverlight应用程序上,如工程结构和在后台代码文件中将XAML与事件相联系。
介绍XAML
让我们来看一个简单的Silverlight应用程序。此应用程序会显示一个带有用户名、密码和登录按钮的基本登录界面。该程序没有任何的后台代码逻辑-我们现在只关注标记部分。图2-1显示了这个登录界面(Windows Vista下的IE7浏览器)
图2-1. 一个简单的登录界面(运行在Vista操作系统中的IE7浏览器)
Silverlight是一种跨平台的技术, 如果您在苹果电脑的Safari浏览器或者Mozilla的火狐浏览器中查看这个登录界面会发现,在不同的浏览器中看到的效果是完全一致的,Silverlight提供了一种切实可行的跨平台框架。
现在让我们来看看用来描述登录界面的XAML内容。如果您新建了一个Silverlight应用程序,您可以将此段代码粘贴到MainPage.xaml文件中去(请确保工程名为XAMLTour,或者找到x:Class属性,并把命名空间修改为与您工程名一致的名称)。接下来,我们将在后续章节继续讨论此段代码诸多方面的细节,比如Grid和Canvas布局控件是如何工作的。
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
Code
1
<UserControl x:Class="XAMLTour.MainPage"
2
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4
Width="400" Height="300">
5
<Canvas Background="White">
6
<Grid Height="140" Width="250" Canvas.Left="25" Canvas.Top="15">
7
<Grid.RowDefinitions>
8
<RowDefinition/>
9
<RowDefinition/>
10
<RowDefinition/>
11
<RowDefinition/>
12
</Grid.RowDefinitions>
13
<Grid.ColumnDefinitions>
14
<ColumnDefinition Width="Auto"/>
15
<ColumnDefinition/>
16
</Grid.ColumnDefinitions>
17
<TextBlock HorizontalAlignment="Center"
18
Text="Please enter your information"
19
Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2"/>
20
<TextBlock Text="Username:" VerticalAlignment="Top"
21
HorizontalAlignment="Right"
22
Grid.Column="0" Grid.Row="1"/>
23
<TextBox VerticalAlignment="Top" Grid.Column="1" Grid.Row="1"/>
24
<TextBlock HorizontalAlignment="Right" VerticalAlignment="Top"
25
Grid.Column="0" Grid.Row="2">
26
Password:
27
</TextBlock>
28
<!--If developing in Silverlight 3, you can use the
29
PasswordBox control also -->
30
<TextBox VerticalAlignment="Top" Grid.Column="1" Grid.Row="2"/>
31
<Button Content="Login" Grid.Row="3" Width="100" Grid.Column="1"
32
HorizontalAlignment="Left"/>
33
</Grid>
34
</Canvas>
35
</UserControl>
XAML提供了一种用于构造和配置对象层次结构的标记语言,如C#。通过C#语言,您也可以生成类似XAML的代码,如下所示:
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
Code
1
grid.Children.Add(headerText);
2
grid.Children.Add(usernameText);
3
grid.Children.Add(usernameInput);
4
grid.Children.Add(passwordText);
5
grid.Children.Add(passwordInput);
6
grid.Children.Add(loginButton);
7
this.Content = canvas;
8
canvas.Children.Add(grid);
9
grid.RowDefinitions.Add(new RowDefinition());
10
grid.RowDefinitions.Add(new RowDefinition());
11
grid.RowDefinitions.Add(new RowDefinition());
12
grid.RowDefinitions.Add(new RowDefinition());
13
ColumnDefinition cd = new ColumnDefinition();
14
cd.Width = new GridLength(0, GridUnitType.Auto);
15
grid.ColumnDefinitions.Add(cd);
16
grid.ColumnDefinitions.Add(new ColumnDefinition());
17
TextBlock headerText = new
18
TextBlock(HorizontalAlignment=HorizontalAlignment.Center);
19
headerText.Text = "Please enter your information";
20
headerText.SetValue(Grid.ColumnProperty, 0);
21
headerText.SetValue(Grid.ColumnSpanProperty, 2);
22
headerText.SetValue(Grid.RowProperty, 0);
23
TextBlock usernameText = new
24
TextBlock(HorizontalAlignment=HorizontalAlignment.Right);
25
usernameText.Text = "Username:";
26
usernameText.SetValue(Grid.ColumnProperty, 0);
27
usernameText.SetValue(Grid.RowProperty, 1);
28
TextBox usernameInput = new TextBox(VerticalAlignment = VerticalAlignment.Top);
29
usernameInput.SetValue(Grid.ColumnProperty, 1);
30
usernameInput.SetValue(Grid.RowProperty, 1);
31
TextBlock passwordText = new
32
TextBlock(HorizontalAlignment = HorizontalAlignment.Right);
33
passwordText.Text = "Password:";
34
passwordText.SetValue(Grid.ColumnProperty, 0);
35
passwordText.SetValue(Grid.RowProperty, 2);
36
//Note: Silverlight 3 also introduces PasswordBox control for the
37
//password input
38
TextBox passwordInput = new TextBox();
39
passwordInput.VerticalAlignment = VerticalAlignment.Top;
40
passwordInput.SetValue(Grid.ColumnProperty, 1);
41
passwordInput.SetValue(Grid.RowProperty, 2);
42
Button loginButton = new Button();
43
loginButton.Content = "Login";
44
loginButton.SetValue(Grid.ColumnProperty, 1);
45
loginButton.SetValue(Grid.RowProperty, 3);
46
loginButton.HorizontalAlignment = HorizontalAlignment.Left;
47![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
loginButton.Width = 100;Canvas canvas = new Canvas
{ Background = new
48
SolidColorBrush(Color.FromArgb(255, 255, 255, 255))};
49
Grid grid = new Grid(Height=140, Width=250);
50
grid.SetValue(Canvas.LeftProperty, 25d);
51
grid.SetValue(Canvas.TopProperty, 15d);
52![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
53
grid.RowDefinitions.Add(new RowDefinition());
54
grid.RowDefinitions.Add(new RowDefinition());
55
grid.RowDefinitions.Add(new RowDefinition());
56
grid.RowDefinitions.Add(new RowDefinition());
57
ColumnDefinition cd = new ColumnDefinition();
58
cd.Width = new GridLength(0, GridUnitType.Auto);
59
grid.ColumnDefinitions.Add(cd);
60
grid.ColumnDefinitions.Add(new ColumnDefinition());
61
TextBlock headerText = new
62
TextBlock(HorizontalAlignment=HorizontalAlignment.Center);
63
headerText.Text = "Please enter your information";
64
headerText.SetValue(Grid.ColumnProperty, 0);
65
headerText.SetValue(Grid.ColumnSpanProperty, 2);
66
headerText.SetValue(Grid.RowProperty, 0);
67
TextBlock usernameText = new
68
TextBlock(HorizontalAlignment=HorizontalAlignment.Right);
69
usernameText.Text = "Username:";
70
usernameText.SetValue(Grid.ColumnProperty, 0);
71
usernameText.SetValue(Grid.RowProperty, 1);
72
TextBox usernameInput = new TextBox(VerticalAlignment = VerticalAlignment.Top);
73
usernameInput.SetValue(Grid.ColumnProperty, 1);
74
usernameInput.SetValue(Grid.RowProperty, 1);
75
TextBlock passwordText = new
76
TextBlock(HorizontalAlignment = HorizontalAlignment.Right);
77
passwordText.Text = "Password:";
78
passwordText.SetValue(Grid.ColumnProperty, 0);
79
passwordText.SetValue(Grid.RowProperty, 2);
80
//Note: Silverlight 3 also introduces PasswordBox control for the
81
//password input
82
TextBox passwordInput = new TextBox();
83
passwordInput.VerticalAlignment = VerticalAlignment.Top;
84
passwordInput.SetValue(Grid.ColumnProperty, 1);
85
passwordInput.SetValue(Grid.RowProperty, 2);
86
Button loginButton = new Button();
87
loginButton.Content = "Login";
88
loginButton.SetValue(Grid.ColumnProperty, 1);
89
loginButton.SetValue(Grid.RowProperty, 3);
90
loginButton.HorizontalAlignment = HorizontalAlignment.Left;
91
loginButton.Width = 100;
92![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
93
grid.Children.Add(headerText);
94
grid.Children.Add(usernameText);
95
grid.Children.Add(usernameInput);
96
grid.Children.Add(passwordText);
97
grid.Children.Add(passwordInput);
98
grid.Children.Add(loginButton);
99
this.Content = canvas;
100
canvas.Children.Add(grid);
101![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
此段C#代码比起XAML代码来显得较为冗长并且难以阅读。C#代码和XAML代码都包含一个编译步骤:显然,C#代码需要进行编译,而XAML文件自从有了后台代码文件后就必须将其打包,并成为XAP文件的一部分。C#也需要软件开发人员来创建用户界面,不管是通过手工编写还是通过设计器设计,如Windows窗体应用程序。而XAML则提供了一种易读并且易于维护的方式来编写设计用户界面。标记显得更易读。XAML并不算是一种全新的标记语言-它易于通过属性或者子元素来配置对象状态。每个元素名(例如UserControl,Canvas等等)直接关联到相应的Silverlight同名对象上。
让我们近距离看看XAML到底有些什么。位于根元素的是UserControl,他是所有其他控件的容器控件。UserControl控件并不是一个可视化控件-如Canvas和Grid这样的布局控件。用户控件实现了一种能够让多种类型控件组合成一个可重用的主控件,这里所说的用户控件与ASP.NET中的用户控件有所区别。我们将在下一章节来讨论Silverlight中的用户控件。
Silverlight为最终在屏幕上呈现的内容提供了丰富的支持。许多控件能够包含任意内容,比如我们可以将ListBox控件的Item定义为一个按钮甚至是另外的ListBox控件。没有什么其他的标记语言能够像XAML这样实现这种组合的自定义用户界面。由于XAML基于XML,因此,元素的描述内容是被嵌套在树层次结构中的。根据XAML的说法,此树被称作逻辑树。
请注意:XAML是大小写敏感的。由于XAML基于XML,因此它具备了XML所有的特征。最重要的是,所有的元素名,属性名等等,都是大小写敏感的。Button和button表示了不同的内容。尽管如此,此规则并不适用于属性值,属性值由Silverilght的XAML分析器自动进行分析处理。
我们再来仔细阅读一下这段XAML代码,我们看到,一个UserControl中包含了一个Canvas,Canvas中包含了一个Grid,而Grid中包含了各种可视化界面元素。您可以在Visual Studio中右键点击设计视图并且选择文档大纲来查看逻辑树中的各个元素,或者通过点击查看菜单并选择其他窗口->文档大纲。通过以上操作可以看到一个用于呈现元素的逻辑树窗口,该窗口可以看到设计界面上有哪些元素。图2-2显示了登录界面所涉及到的所有元素。该逻辑树视图与WPF中的逻辑树视图有细微的差别,因为文档大纲关注的是XAML中显式查找到的是什么元素。举例来说,如果一个ListBoxItem对象包含一个Content属性,类型转换字符串并不会显示出来。尽管如此,创建一个Button作为ListBoxItem的子对象则会使Button显示在文档大纲视图中。
图2-2. 用于描述登录界面元素的文档大纲视图
命名空间
现在,我们将详细介绍XAML的文件结构。每个XAML文件中都有两个非常重要的位于根元素的命名空间。(如果您使用Expression Blend创建Silverlight应用程序会发现Blend自动的添加了另外两个命名空间,但是我们在此只关注这两个最重要的命名空间)。第一个是默认的命名空间,指定为xmlns="http://schemas.
microsoft.com/winfx/2006/xaml/presentation"。此命名空间包含了Silverilght中各种元素对应的对象,如UserControl,Canvas和Grid。在Visual Studio中,如果您删除了这段定义,则会显示蓝色的波浪线表示代码出现了问题。
其余的命名空间定义包含了Silverlight特定的扩展。在此命名空间中的元素会以x:打头。这是一种约定俗成的方式,所有的Silverlight相关文档都会遵循这一规则。表2-1描述了此命名空间最重要的内容。
表2-1.x:命名空间的特性
特性 |
描述 |
x:Class |
将各个部分类组合在一起。验证语法:x:Class="namespace.classname"和x:Class="namespace.classname;assembly=assemblyname"。XAML页面会生成类的部分代码,再由后台代码进行组合。 |
x:Key |
在XAML中提供了被资源定义的唯一标识符,通过标记扩展来引用资源极其重要。标识符必须以字母、下划线开头并且只能包含字母、数字和下划线。 |
x:Name |
在XAML中为对象元素提供了唯一标识符用来通过后台代码来访问这些对象元素。在资源文件中此方式不适用(在资源文件中应该使用x:Key来代替x:Name)。许多元素都有Name属性,当Name和x:Name都可使用时,只能设置其中一个。标识符必须以字母开头或者下划线,并且只能包含字母、数字和下划线。 |
x:Null |
和C#中的null类似(在VB.NET中则是Nothing)。可以通过标记扩展({x:Null})或者通过属性元素(<x:Null/>)。 |