如果我们使用Visual Studio 2005来开发一个XAML程序,那与上述的手动创建XAML程序过程来说是相对便捷的。你可以直接选择一个WinFX模板来创建特定类型的WPF程序,Visual Studio会自动为该WPF程序创建相应的项目文件和应用程序清单。现在我们可以创建的WPF程序类型有如下的四种:
1. WinFX Wndows Application
2. WinFX Web Browser Application
3. WinFX Service Library
4. WinFX Customer Control Library
然而,针对WinFX开发的Visual Studio版本还没有正式推出,所以Visual Studio 2005缺乏对WinFX程序开发这方面的一些完善支持,为此要编辑XAML和相应的代码后置文件(.xaml.cs)时,有时还是需要开发人员手动地进行编辑。
在这里假设你已经安装好了运行XAML所需的软件环境,现在我们来使用Visual Studio 2005创建一个WPF程序。至于是选择WinFX Wndows Application模板还是WinFX Web Browser Application模板取决于你所要创建的是宿主于浏览器的程序还是窗体程序。现在我们在"新建项目"对话框中的WinFX Web Browser Application模板,输入该WPF程序的项目名称,并选择好程序保存在硬盘上的位置,点击"确定"按钮,Visual Studio就自动为该WPF程序生成默认的XAML和代码后置文件。
提示:
无论你是否使用Visual Studio,在创建一个WinFX Wndows Application和一个WinFX Web Browser Application时,各自的.xaml文件代码还是存在一些细微差别的。在一个Browser Application中,默认起始页的根元素为Page。而一个Wndows Application中,默认起始页的根元素为Window。而Window类是无法在Browser Application中使用的,这是因为运行在浏览器中的WPF程序是在部分信任的沙箱内操作(沙箱能够防止客户端计算机受到恶意应用程序的侵害),为此它没有打开一个新Windows窗体的权限。
在解决方案资源管理器窗口中,可以看到Visual Studio为当前WPF程序所自动生成的XAML和代码后置文件。由于在Visual Studio中会自动生成相应的项目文件,使用我们不必详细了解该Browser Application在生成时其底层的实现细节。但是由于WPF程序和应用程序定义文件和相关的XAML页面文件戚戚相关,为此最好还是详细了解下各个文件的具体内容,下面我们通过双击解决方案资源管理器中的文件图标打开相应的文件,在默认状态下,一个.xaml文件存在三个试图方式,分别为设计试图、XAML试图和源码试图。如果要查看相应的XAML代码的话,你可以点击XAML按钮切换到XAML试图状态下。这是打开应用程序定义文件App.xaml的相应界面:
点击XAML试图按钮后,App.xaml页面对应的XAML代码如下
01 <Application x:Class="BrowserDemo.App" 02 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 03 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 04 StartupUri="Page1.xaml" 05 > 06 <Application.Resources> 07 08 </Application.Resources> 09 </Application> |
在第1行代码处我们可以看到,在应用程序定义文件中我们使用了Application元素,并且用x:Class 属性指定了一个与之关联的C#不完全类(后一个程序清单的第14行代码所示),而后在程序编译时,会自动将应用程序定义文件和包含关联C#不完全类的代码后置文件这两部分结合在一起,从而创建一个完整的BrowserDemo命名空间下的App类,注意,BrowserDemo.App类是从WPF提供的System.Windows.Application类中派生的。第4行代码使用了StartupUri属性为该WPF程序指定首次运行程序时要加载的XAML页面文件。在一个Browser Application类型的WPF程序中,我们可以添加多个XAML页面,并支持在这些页面间进行跳转和切换。
提示:
而App.xaml.cs的代码如下(可以通过App.xaml页面的Source按钮切换到源码试图):
01 using System; 02 using System.Windows; 03 using System.Windows.Navigation; 04 using System.Data; 05 using System.Xml; 06 using System.Configuration; 07 08 namespace BrowserDemo 09 { 10 /// <summary> 11 /// Interaction logic for App.xaml 12 /// </summary> 13 14 public partial class App : Application 15 { 16 17 } 18 } |
Page1.xaml页面对应的XAML代码如下:
01 <Page x:Class="BrowserDemo.Page1" 02 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 03 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 04 Title="Page1" 05 > 06 <Grid> 07 </Grid> 08 </Page> |
我们在第1行代码处用x:Class属性指定的BrowserDemo.App类是从WPF提供的System.Windows.Application类中派生的,并且用属性Title指定了该页面在呈现时的标题。第6-8行代码使用了一个Grid元素,微软推荐开发人员使用该元素来布局XAML页面上的各个界面元素,这是因为Grid元素在定位页面上的各个元素方面有着极大的灵活性,至于该元素的具体用法将在本章的后续章节进行介绍。
01 using System; 02 using System.Collections.Generic; 03 using System.Text; 04 using System.Windows; 05 using System.Windows.Controls; 06 using System.Windows.Data; 07 using System.Windows.Documents; 08 using System.Windows.Input; 09 using System.Windows.Media; 10 using System.Windows.Media.Imaging; 11 using System.Windows.Navigation; 12 using System.Windows.Shapes; 13 14 namespace BrowserDemo 15 { 16 /// <summary> 17 /// Interaction logic for Page1.xaml 18 /// </summary> 19 20 public partial class Page1 : Page 21 { 22 23 public Page1() 24 { 25 InitializeComponent(); 26 } 27 28 } 29 } |
现在我们在这个Browser Application的Page1.xaml页面上添加一个按钮,并对该按钮的单击事件添加一个事件处理方法以显示信息。首先我们在工具箱上拖拽一个Button控件,切换到XAML视图后,你会发现在<Grid>…</Grid>两元素之间添加了一个Button元素,我们可以设置其相应的属性,最终Page1.xaml的代码如下:
01 <Page x:Class="BrowserDemo.Page1" 02 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 03 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 04 Title="Page1" 05 > 06 <Grid> 07 <Button Height="100" Width="300" FontSize="24" Background="Aqua" 08 Name="MyButton" Content="Click Me" Click="ChangeMe" > 09 </Button> 10 </Grid> 11 </Page> |
由于要处理按钮的单击事件,为此我们要编写相应的事件处理方法。其代码如下
01 void ChangeMe(object sender, RoutedEventArgs eventArgs) 02 { 03 count++; 04 MyButton.Content = "You have clicked " + count + " times!"; 05 } |
如上述的代码所示,我们每点击一次按钮,都会导致该按钮上显示的内容发生改变(每次count的值都自增1)。
而事件处理代码我们一般是在XAML页面对应的代码后置文件中进行编写。我们将事件处理代码要添加到Page1.xaml页面的代码后置文件Page1.xaml.cs中,改变后的代码如下:
01 using System; 02 using System.Collections.Generic; 03 using System.Text; 04 using System.Windows; 05 using System.Windows.Controls; 06 using System.Windows.Data; 07 using System.Windows.Documents; 08 using System.Windows.Input; 09 using System.Windows.Media; 10 using System.Windows.Media.Imaging; 11 using System.Windows.Navigation; 12 using System.Windows.Shapes; 13 14 namespace BrowserDemo 15 { 16 /// <summary> 17 /// Interaction logic for Page1.xaml 18 /// </summary> 19 20 public partial class Page1 : Page 21 { 22 int count = 0; 23 public Page1() 24 { 25 InitializeComponent(); 26 } 27 28 void ChangeMe(object sender, RoutedEventArgs e) 29 { 30 count++; 31 MyButton.Content = "You have clicked " + count + " times!"; 32 } 33 } 34 } |
我们在第22行定义了一个名为count的变量,并初始化其值为0。在第28行代码处是Button按钮的事件处理方法,这里的事件处理方法名ChangeMe就是由Page1.xaml中的Button元素的Click指定的。因为在一个WPF程序中可能包含若干个Button元素,所以你可以在XAML文件用Name属性为该Button元素指定一个惟一的名称,这里为MyButton。以后在对应的代码后置文件中应用该Button元素时,就不用再对这个元素进行声明了。并且在编译时,Button元素的声明和相应的事件处理方法将"合并"到同一个类中,这里为BrowserDemo.Page1。
提示:
在添加了元素和相应的处理方法、逻辑后,我们就可以采用和以前类似的用Visual Studio生成.NET应用程序的方式来生成WPF程序。也就是说我们可以使用Visual Studio菜单上的"生成"-"生成XX"(XX为项目名)命令来编译程序,编译完毕后,就可以对该程序进行测试、调试和部署。
保存文件的最后一次改动后,再使用"启动调试"按钮生成该Browser Application程序,最后得到的呈现效果如下:
下图是点击按钮10次后的显示效果:
上述的整个实现过程对于.NET开发人员来说应该是非常熟悉的,因为XAML页面有点类似于ASP.NET中的Web窗体,都是用来构建程序的界面布局。而XAML页面对应的代码后置文件则等类似于ASP.NET中用来处理事件和用户请求信息的服务器端代码。
我们在前面提及过,使用Visual Studio来创建一个WPF程序时,无需开发人员编写项目文件,而且也不用考虑微软新一代统一生成平台MSBuild的运作方式。上述的这些必需的文件都会由Visual Studio自动给开发人员生成,你仅需考虑WPF程序中的应用程序定义文件和XAML页面文件即可。