'Avalon' Quick Start
注:本文翻译自Microsoft® WinFX™ SDK文档,并进行了适当删减。
首先,“Avalon”是一个开发平台,所以最好的学习方式就是使用“Avalon”写一些简单的应用程序。本教程告诉你如何开始使用“Avalon”。
本教程包含以下内容: 概要 Hello World 示例程序 使用“XAML”实现用户界面 编写动态“XAML”页面 创建多页面应用程序
概要
下面是有关“Avalon”的一些要点。 “Avalon” 基于托管代码。“可扩展应用程序标记语言(Extensible Application Markup Language – XAML(音zammel))” 现在支持基于C#和Microsoft Visual Basic .NET的应用程序。如果仅使用程序代码(不使用XAML)编写“Avalon”应用程序,则可以使用任何CLR语言。 “Avalon”应用程序通常由一个NavigationApplication对象和一组页面组成。NavigationApplication对象始终贯串应用程序的生存期,可以通过它控制顶级事件(top-level events),在各页面间共享代码和状态。用户界面(UI)通常用一种称作“XAML”的标记语言来实现。标记符号用来控制页面输出,显示文本和图像,和用户交互等等。用户可以在各页面间跳转浏览,这一点非常像一个Web应用程序。 “XAML”使用标记来在“Avalon”对象模型上编程。每个标签都映射到一个类,每个标记中的属性都映射到一个类的属性。在编译工程时,“XAML”解析器将标记转换为基于等价对象模型的代码。相反,任何用“XAML”实现的都可以直接使用对象模型来实现。 “XAML”页面包含程序代码和标记。例如,如果要处理页面上一个XAML元素产生的事件,那么你需要在程序代码中实现事件处理程序。“Avalon”应用程序通常将程序代码放在一个分开的code-behind文件里。当生成应用程序时,“XAML”解析器将页面的XAML部分生成为一个局部类,然后与code-behind文件中的局部类合并,最后编译器编译这个合并后的类。 在运行“Avalon”应用程序前必须编译它,即使页面只包含XAML标记。
Hello World 示例程序
每个编程平台都有一个“Hello World”示例程序,一个能够马上运行的简单示例。“Avalon”版的Hello World是一个含有3个元素的XAML页面。
HTML 代码:<Page xmlns='http://schemas.microsoft.com/winfx/avalon/2005' xmlns:x='http://schemas.microsoft.com/winfx/xaml/2005' x: <StackPanel> <TextBlock>Hello World</TextBlock> </StackPanel></Page>
请确定你已经安装了Microsoft Visual Studio 2005 和WinFX Software Development Kit (SDK). 要运行这个示例,你需要先在Visual Studio 2005中新建一个工程,然后编译翻译程序。 1. 打开Visual Studio 2005,选择菜单File | New | Project.
2. 选择Visual C# 或 Visual Basic 工程类型.
3. 在Visual Studio Installed Templates中选择 Avalon Navigation Application 工程模板。工程名称为QuickStart_1,然后单击OK 新建工程。
4. 查看Solution Explorer ,打开Page1.xaml.用上面的代码替换文件内容。可以忽略工程中的其它文件。
5. 按F5编译并运行程序。虽然很简单,但是它展示了“XAML”的基本功能。
使用'XAML'实现用户界面
如前所述,'XAML' 是一种可扩展标记语言(XML)- 它提供了一种灵活且功能强大的方式来帮助你的应用程序实现用户界面。 'XAML'由一些元素组成,这些元素分为下面几类。 Root 表示页面根元素。 Panel 处理页面输出,并作为元素的容器。 Control 处理用户交互。 Document 处理文档界面。 Shape 处理矢量图形。元素通过标签记录在.xaml源文件中。标签的记录规则和xml相同。 <Tag1>内容</Tag1> <Tag2/> 大部分元素都包含一些属性。通过给特定的属性赋值,可以改变元素外观、附加事件处理等。下面的例子显示一个Button标签,内部文本为'My Button',Height为30象素。
<Button Height='30'>My Button</Button> 页面元素组织为多个层次,其中只能有一个根元素。Page是最常用的根元素。 根元素可以有一个子元素,比如一个Panel元素。它作为一个页面内容的容器,并控制页面级属性。 元素可以触发各种事件,通常用来响应用户动作,比如鼠标Click事件。通过附加事件处理程序,可以使页面动态响应用户动作。要附加事件处理程序,只需要将事件处理程序名称赋值给相应事件。下面的例子将一个名为'HandleClick'的事件处理程序赋值给一个Button的Click事件。事件处理程序实现在后台代码(code-behind)文件中。
<Button Click='HandleClick'>My Button</Button> 元素描述了一个可通过托管代码访问的对象模型。<Button>标签对应Button对象。对象模型允许你操作页面上的元素,并且提供了一些无法通过'XAML'实现的能力。
测试Hello World示例程序
如果你测试前面的“Hello World”示例,你应该注意到它由3个元素组成了一个很简单的层次结构。 页面的根元素是Page。这是最常用的根元素。Page元素包含了3个属性,这3个属性是每个根元素必须的。其中,两个xmlns属性定义了XML名称空间。每个根元素都必须包含这些名称空间的声明,因为它们能够使XAML标签和相关联的对象模型间建立连接。最后一个属性指定了XAML解析器通过标记产生的局部类的名称空间及名称。如果页面有code-behind文件,那么其局部类的名称空间和类名必须与根元素中所指定的相同。 根元素的子元素是一个StackPanel元素。这种面板将其子元素横向或者纵向堆叠在一起。因为只有一个面板元素,所以它代表了窗口的整个客户区。 StackPanel元素有一个子元素,一个TextBlock元素。元素的内容是一个字符串'Hello World',它将会在运行时显示。默认情况下,TextBlock元素将文本显示在窗口的左上角。
创建'XAML'页面
创建XAML页面很简单,你只需要记住一些基本的规则。因为XAML是基于XML的,下面是一些使用标签的基本规则。 元素能够包含文本内容和其他元素。如果包含内容或其它元素,那么必须包含在开始标签和结束标签之间。如果元素不包含内容,就只需要单个标签,但是必须使用/>结束,而不是>。例如: <Tag1>文本字符串</Tag1> <Tag1><Tag2>文本字符串</Tag2><Tag1> <Tag2/> 元素被组织成层次结构。每个页面只能有一个根元素。所有其他的元素必须是其子元素。 'XAML'是大小写敏感的,所以必须要注意名称的大小写。<TAG>和<tag>是不同的。 标签不能交叠嵌套。下面的结构是错误的。 <Tag1><Tag2></Tag1></Tag2> 属性值必须被单引号或双引号包括。例如: <Border Background='LightBlue'>...</Border> 元素包含的内容文本必须是well-formed,这代表字符串不能包含特殊字符,比如'<'或'&'。如果要使用包含特殊字符的文本,那么必须将其包含在CDATA块里面。例如: <![CDATA[字符串...]]>
简单布局
XAML在Avalon应用程序里的一个主要作用是控制页面布局。XAML布局通常使用一组称为面板的元素来控制。有许多用来控制不同布局的面板元素。最简单的页面布局由一个面板元素作为页面的根元素,它包含一个或多个子元素来描述用户界面。下面的例子用一个StackPanel作为其根元素。这种面板将其子元素横向或者纵向堆叠在一起。其子元素由几个Button控件纵向堆叠在一起。
看起来就是这个样子:
HTML 代码:<Page xmlns='http://schemas.microsoft.com/winfx/avalon/2005' xmlns:x='http://schemas.microsoft.com/winfx/xaml/2005' x: <StackPanel> <Button HorizontalAlignment='Left' Width='100' Margin='10,10,10,10'>Button 1</Button> <Button HorizontalAlignment='Left' Width='100' Margin='10,10,10,10'>Button 2</Button> <Button HorizontalAlignment='Left' Width='100' Margin='10,10,10,10'>Button 3</Button> </StackPanel></Page>
默认情况下,按钮被纵向放置。如果要横向放置,可以将StackPanel元素的Orientation属性设置为'Horizontal'。按钮的定位由HorizontalAlignment属性指定。默认情况下,按钮居中对齐。这个例子是左对齐的,所以HorizontalAlignment属性被设置为'Left'。
这个例子还使用了两个有用的属性来调整元素外观,Width属性和Margin属性。Width属性指定了元素的宽度,Margin属性控制与临近元素的间距,字符串中的4个整数分别指定了左,上,右,下的间距。这些属性的默认单位是象素,所以这里的按钮被设置为100象素宽,各边有10象素的间距。
注意:在Avalon里,象素并不等于显示器的物理象素。而是一个设备无关的单位,这里的1象素=1/96英寸。
要运行这个示例,首先创建一个'Avalon' Navigation Application工程,命名为QuickStart_2,并使用示例代码替代Page1.xaml文件里的代码。然后编译并运行程序,和'Hello World'程序一样。当点击按钮时,按钮会呈现按下状态,但是不会有任何反应,除非实现了Click事件的处理程序,后面会讨论。
复杂布局
你通常需要比单面板更灵活方式来布局页面。一种简历复杂布局的方式是使用一个面板作为其它面板的容器。下面的XAML示例介绍了DockPanel元素。这个面板主要用来将页面分成多个区域。没个区域都可以包含一个或多个控件。可以通过设置元素的DockPanel.Dock属性来指定元素在DockPanel中的位置。最后一个元素将充满页面的剩余区域。
这个例子告诉你怎样使用DockPanel, StackPanel, Button, 和TextBlock元素来创建一个稍微复杂的页面布局。
注意这个示例里的布局元素被指定了背景颜色。当创建复杂布局时,它帮助你为每个布局元素指定不同的背景颜色。它使每个元素占用的区域变明显,以帮助确定布局的正确性。两个DockPanel都有一个ID属性被设置。在这个例子里,它知识为了方便说明。在后面你将看到怎样在code-behind文件里使用元素ID来访问元素属性。
这个例子看起来像这样:
代码如下:
HTML 代码:<Page xmlns='http://schemas.microsoft.com/winfx/avalon/2005' xmlns:x='http://schemas.microsoft.com/winfx/xaml/2005' x: <DockPanel ID='RootPanel'> <TextBlock Background='LightBlue' DockPanel.Dock='Top'>Some Text</TextBlock> <TextBlock DockPanel.Dock='Bottom' Background='LightYellow'>Some text at the bottom of the page.</TextBlock> <TextBlock DockPanel.Dock='Left' Background='Lavender'>Some More Text</TextBlock> <DockPanel Background='Bisque' ID='InnerPanel'> <StackPanel DockPanel.Dock='Top'> <Button HorizontalAlignment='Left' Height='30px' Width='100px' Margin='10,10,10,10'>Button1</Button> <Button HorizontalAlignment='Left' Height='30px' Width='100px' Margin='10,10,10,10'>Button2</Button> </StackPanel> <TextBlock Background='LightGreen'>Some Text Below the Buttons</TextBlock> </DockPanel> </DockPanel></Page>
这个例子中的根面板是ID为'RootPanel'的DockPanel元素。有两个TextBlock元素,一个停靠在面板顶部,一个在底部。下一个TextBlock元素停靠在面板左边,它被放在前面的两个TextBlock元素之间。ID为'InnerPanel'的DockPanel元素是根元素'RootPanel'的最后一个子元素,所以它覆盖了剩余的全部区域。它包含一个StackPanel元素,其中又有两个按钮。TextBlock元素是'InnerPanel'的最后一个元素,所以它覆盖了剩余的全部区域。
要运行这个示例,首先创建一个'Avalon' Navigation Application工程,命名为QuickStart_3, 并使用示例代码替代Page1.xaml文件里的代码。然后编译并运行程序,和'Hello World'程序一样。
试着修改现有的属性值或增加属性来更改页面布局,比如Height或Width。另外,DockPanel元素的行为依赖于.xaml文件中元素的顺序及DockPanel.Dock属性的设置。试着修改这些来看看页面布局的变化。
制作动态'XAML'页面
你现在已经能够使用XAML来显示信息,但是用户通常需要与应用程序交互。如果要使页面能够响应用户动作,你需要给元素附上事件处理程序,并且用程序代码实现事件处理程序,例如C#。下面这个例子由包含一个按钮的StackPanel元素组成。当你点击这个按钮时,事件处理程序将按钮文本由'Click me'变为'Hello World'。
这个界面的XAML代码如下:
HTML 代码:<Page xmlns='http://schemas.microsoft.com/winfx/avalon/2005' xmlns:x='http://schemas.microsoft.com/winfx/xaml/2005' x: <StackPanel> <Button HorizontalAlignment='Left' Width='100' Margin='10,10,10,10' Click='HandleClick' ID='Button1'>Click Me</Button> </StackPanel></Page>
这个例子和前面三个按钮的示例程序很相似,但是只有一个按钮。不过这个按钮包含了一个新的属性:Click。这个属性将一个名为HandleClick的事件处理程序附加到Click事件上。这个处理程序实现在页面的code-behind文件里,这个后面再讨论。你可以给事件处理程序一个任何你想要的名称。
要实现这个示例程序,新建一个'Avalon' Navigation Application工程,命名为QuickStart_4,然后将Page1.xaml文件内容用上面的代码替换。这个示例程序包含程序代码,所以你也可以使用Visual Basic .NET来实现。那么新建项目时应该选择Visual Basic项目类型。
Click事件的处理程序实现在页面的code-behind文件里。一般习惯将code-behind文件命名为与.xaml文件一样。然后加上特定语言的扩展名。所以这里的code-behind文件名为Page1.xaml.cs。要使用C#实现事件处理程序,使用下面的代码替换默认的局部类的实现。
代码:using System;using System.Windows;using System.Windows.Controls;namespace QuickStart_4{public partial class Page1 : Page{ void HandleClick(object sender, RoutedEventArgs e) { Button1.Content = 'Hello World'; } }}
你也可以新建一个Visual Basic项目,使用Visual Basic .NET来实现这个应用程序。使用与C#示例一样的XAML代码。Visual Basic .NET版本的代码如下:
代码:Imports SystemImports System.WindowsImports System.Windows.ControlsNamespace QuickStart_4_VB Partial Class Page1 Inherits Page Sub HandleClick(ByVal Sender As Object, ByVal args As RoutedEventArgs) Button1.Content = 'Hello World' End Sub 'HandleClick End ClassEnd Namespace
注意Page1是一个局部类。这种类的实现可以在多个文件中。这样做的原因是:当应用程序被编译时,Page1.xaml中的XAML代码被转换为一个等效的局部类,类名和名称空间就是根元素的x:Class属性所指定的名称。然后这个局部类与code-behind文件中的局部类合并成一个类,最后这个类被编译成最终的可执行的页面。
注意:x:Class属性指定的名称空间和类名称必须和code-behind文件里的名称相同。code-behind文件里的局部类也必须继承自根元素的类。否则CLR无法合并两个局部类。
Page1类有一个方法:HandleClick。它就是在Page1.xaml文件中所指定的Click事件处理程序。当Click事件发生时,这个处理程序会被调用。这个事件的委托是RoutedEventHandler,它定义了事件处理程序的签名。当Page1.xaml文件被编译时,按钮的ID值作为了Button对象的变量名称。你可以在code-behind文件中使用这个ID来访问这个按钮的属性,方法和事件。在这个例子里,事件处理程序通过将按钮的Content属性设置为'Hello World'来改变按钮上的文本。
将Page1.xaml.cs或Page1.xaml.vb文件的内容替换为上面相应的代码,然后按F5编译并运行程序。
创建多页面应用程序
'Avalon'应用程序通常由多个动态'XAML'页面组成。用户可以从一个页面到另一个页面,就像Web应用程序一样。新页面代替旧页面,就像从一个HTML页面转到另一个。也可以选择通过打开新窗口来显示新的页面。
最简单的定位到新页面的方法是使用HyperLink元素,它可以用XAML来实现。这个元素使用应用程序的NavigationApplication对象来定位到指定的目标页面。下面的例子使用HyperLink元素创建了一个简单的有两个页面的应用程序。在开始的页面中点击超链接就会定位到第二个页面,反之亦然。开始页面的代码如下:
HTML 代码:<Page xmlns='http://schemas.microsoft.com/winfx/avalon/2005' xmlns:x='http://schemas.microsoft.com/winfx/xaml/2005' x: <StackPanel Background='LightBlue'> <TextBlock Margin='10,10,10,10'>Start Page</TextBlock> <HyperLink NavigateUri='Page2.xaml' HorizontalAlignment='Left' Margin='10,10,10,10'>Go To Page 2</HyperLink> </StackPanel></Page>
这个页面有一个StackPanel元素作为根面板,它有两个子元素,一个TextBlock元素和一个HyperLink元素。HyperLink元素的NavigateUri属性设置为目标页面的.xaml文件名称。它与Page1.xaml位于同一个文件夹,所以可以直接使用文件名。点击超链接加载并呈现Page2.xaml,它替换了应用程序窗口中Page1.xaml的内容。
要实现这个示例程序,新建一个'Avalon' Navigation Application项目,命名为QuickStart_5,使用上面的代码替换Page1.xaml.的内容。
要创建Page2.xaml,右键单击Solution Explorer中的项目名称,选择Add New Item,然后选择StackPanel模板。它默认命名为'Page2',点击Open,Visual Studio .NET会添加两个文件到项目中,Page2.xaml和Page2.xaml.cs。用下面的代码替换Page2.xaml文件的内容。
HTML 代码:<Page xmlns='http://schemas.microsoft.com/winfx/avalon/2005' xmlns:x='http://schemas.microsoft.com/winfx/xaml/2005' x: <StackPanel Background='LightGreen'> <TextBlock DockPanel.Dock='Top' Margin='10,10,10,10'>Page 2</TextBlock> <HyperLink NavigateUri='Page1.xaml' HorizontalAlignment='Left' Margin='10,10,10,10'>Go To The Start Page</HyperLink> </StackPanel></Page>
这个文件和Page.xaml的最明显区别是HyperLink元素的NavigateUri属性被设置成'Page1.xaml'。按F5编译并运行程序。