1.5 在Xaml中创建Application
上面的例子是使用C#代码来创建Application的类。实际上在WPF应用程序中更常用的是使用Xaml来创建Application类实例。上面提到在Visual Studio里创建WPF应用程序通常使用项目模板,现在来考察使用Visual Studio项目模板创建WPF应用程序的过程。在File菜单中选择“New Project”,Visual Studio会显示图1-4所示的会话框,你可以选择WPF Application(桌面应用程序)或WPF Browser Application(Silverlight应用程序)。
当选择WPF Application项目模板时,Visual Studio自动创建4个文件:App.xaml、App.xaml.cs、Window1.xaml和Window1.xaml.cs。这4个文件移植了两个类,App.xaml和App.xaml.cs创建的是App类,它从Application类中派生出来。Window1.xaml和Window1.xaml.cs创建的是Window1类,它从类Window中派生出来。让我们来看一下App.xaml:
<Application x:Class=" Yingbao.Chapter1.WPFStartUp.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="Window1.xaml"> <Application.Resources> </Application.Resources> </Application>
图1-4 Visual Studio中的项目模板
x:Class属性把xaml所对应的后台C#类联系起来,在这里是Yingbao.Chapter1.WPFStartUp.App,其中App是类名,Yingbao.Chapter1.WPFStartup是命名空间。App.xaml在编译后产生一个部分类,它位于所创建的项目目录下的obj\Debug子目录中,文件名为App.g.cs。这个文件中的内容如下:
public partial class App : System.Windows.Application { [System.Diagnostics.DebuggerNonUserCodeAttribute()] public void InitializeComponent() { #line 4 "..\..\App.xaml" this.StartupUri = new System.Uri("Window1.xaml", System.UriKind.Relative); #line default #line hidden } [System.STAThreadAttribute()] [System.Diagnostics.DebuggerNonUserCodeAttribute()] public static void Main() { Yingbao.Chapter1.WPFStartUp.App app = new Yingbao.Chapter1.WPFStartUp.App(); app.InitializeComponent(); app.Run(); } }
它在App类中加入了两个方法,InitializeComponent和Main。Main方法和我们在前面直接创建HelloWPF类时所移植的Main方法类似,由于一个应用程序只能有一个入口点,所以在App.xaml.cs中不能再移植Main方法。在InitializeComponent()方法中,设置了StartupUri属性:
this.StartupUri = new System.Uri("Window1.xaml", System.UriKind.Relative);
它是对App.xaml中的StartupUri="Window1.xaml"翻译。
我们可以在App.cs中移植应用程序的逻辑,下面是App.cs中的App部分类:
namespace Yingbao.Chapter1.WPFStartUp { public partial class App : Application { } }
Visual Studio为我们产生一个框架。
与App类似,Visual Studio产生的Window1.xaml,也是一个部分类,Window1的另一部分类在C#中。
<Window x:Class="Yingbao.Chapter1.WPFStartUp.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="300" Width="300"> <Grid> </Grid> </Window>
其中的x:Class属性也是把XAML和后台的C#类联系起来。
namespace Yingbao.Chapter1.WPFStartUp { public partial class Window1 : Window { public Window1() { InitializeComponent(); } } }
它只产生一个构造函数Window1,其中调用了InitializeComponent方法,InitializeComponent在哪里呢?在xaml编译后产生的AppWin.g.cs文件中:
namespace Yingbao.Chapter1.WPFStartUp { public partial class AppWin : System.Windows.Window, System.Windows.Markup.IComponentConnector { private bool _contentLoaded; [System.Diagnostics.DebuggerNonUserCodeAttribute()] public void InitializeComponent() { if (_contentLoaded) { return; _contentLoaded = true; System.Uri resourceLocater = new System.Uri("/WPFStartUp;component/window1.xaml", System.UriKind.Relative); #line 1 "..\..\Window1.xaml" System.Windows.Application.LoadComponent(this, resourceLocater); #line default #line hidden } [System.Diagnostics.DebuggerNonUserCodeAttribute()] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.Ed itorBrowsableState.Never)] [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Des ign", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")] void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) { this._contentLoaded = true; } } }
本书以下的章节都是以Visual StudioWPF项目模板所产生的代码为基础,小结一下:
● xaml中的x:Class属性把xaml和后台C#类联系起来。
● Visual Studio利用.NET 2.0引入的部分类(partial class)技术,把一个类分为两部分表述:一个是xaml文件,一个是C#文件。编译后,xaml文件会产生一个后缀为.g.cs的C#文件,是xaml所产生的部分类。
● Application中的StartupUri设置了应用程序启动时的主窗口。