http://tech.it168.com/msoft/2008-01-24/200801241039873.shtml
Application类是构建WPF应用程序过程中最常见和最重要的对象之一,其核心功能是封装整个WPF应用程序。换句话说,每个WPF应用程序都是一个Application对象,其支持各种核心应用程序服务。在本文中,笔者将详细讲解Application对象的功能、创建和访问Application对象的方法、应用程序中的事件。这些内容将为开发人员创建WPF应用程序奠定技术基础。
1. Application对象的功能
System.Windows.Application是构建WPF应用程序过程中最为重要和常用的类,其继承自DispatcherObject类。Application类的实例是Application对象。每个WPF应用程序都是通过Application对象来展现自己。Application对象功能众多,主要包括以下功能:
创建和管理常见应用程序架构;
跟踪应用程序生命周期,并与实现与之交互;
获取和处理命令行参数;
共享应用程序范围的属性和资源;
检测和响应未处理异常;
返回退出代码(exit code);
管理独立应用程序(standalone application)中的窗口;
跟踪和管理导航;
由以上介绍的功能可知,Application类功能非常强大。开发人员对于这些功能的了解是不可能一蹴而就的,下面以介绍创建和访问Application对象的方法为起点来讲解这个重要对象。
2. 创建和访问Application对象
通常创建Application对象的方法有三种:(1)使用XAML中的<Application>元素定义;(2)使用C#等代码定义;(3)使用<Application>元素和C#代码共同定义Application对象。
(1)使用<Application>元素定义
这种方法的核心是使用XAML中的<Application>元素,如下代码所示:
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" />
以上代码仅设置了Application元素的命名空间属性(xmlns和xmlns:x)。由于没有设置启动时所要显示的内容,因此在启动应用程序后将看不到任何信息。这样实现的意义显然不是很大。应用程序启动的内容可通过在<Application>元素中设置StartupUri属性来实现。例如,设置StartupUri ="MyWpf.xaml"。接下来,开发人员可创建一个名为MyWpf.xaml的文件,并在其中定义根元素,子元素以及业务逻辑等。需要注意的是,在其中定义的根元素应该是上一篇系列文章中介绍的根元素,例如Window、Page等元素。
(2)使用C#等代码定义
这种方法的核心是使用C#代码,在类中应用Application类的构造函数,如“Application app = new Application();”。请看如下代码,当运行代码时,将显示一个空白窗口。
using System;
using System.Windows;
namespace WpfAppObj
{
class AppObj
{
[STAThread]
static void Main(string[] args)
{
//创建Application对象
Application app = new Application();
//创建Window对象,并设置属性
Window win = new Window();
win.Title = "创建Application对象";
//调用Application对象的Run方法,显示主窗口
app.Run(win);
}
}
}
(3)使用<Application>元素和C#代码共同定义
这种方法比较常用,其灵活性比较强。首先,使用<Application>元素定义Application对象并设置相关属性,尤其是设置x:Application属性,以便将该XAML与接下来要实现的C#代码关联起来。最后,使用C#代码编写类文件。
XAML文件代码如下所示:
<Application
x:Class="AppObj"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" />
using System;
using System.Windows;
public partial class AppObj : Application
{
public AppObj()
{
InitializeComponent();
}
}
需要读者注意的是,在使用方法(1)和方法(3)时,并不需要如方法(2)那样编写Main方法,编译器可自动完成该工作。
当开发人员使用以上方法,通过Application对象创建应用程序之后,很自然的需要访问当前的应用程序。这是通过Application类的Current属性来实现。
举例而言,当开发人员使用上一节中的方法(2)创建一个包含窗口的应用程序之后,为了实现访问当前应用程序窗口的Title属性,可使用如下代码:
Window main = Application.Current.MainWindow;
MessageBox.Show("窗口的Title属性值是" + main.Title);
当然,在有效获取表示当前应用程序的Application对象之后,不仅可以访问应用程序的各种属性,而且还可以访问其他任何方法等成员,甚至是为主窗口添加的事件等。
3. 应用程序的事件
WPF应用程序的生命周期中包括多个事件,这些事件与Application对象之间关系非常紧密。这些事件包括Startup、Exit、SessionEnding、Activated、Deactivated、DispatcherUnhandledException等。如图1所示,显示了独立应用程序中的事件发生过程。
![](https://i-blog.csdnimg.cn/blog_migrate/45ffd55e127451ec9b7af4aca55cdadb.jpeg)
图1所示的过程简单而清晰,但是需要注意的是,图中箭头所指的方向以及连接情况。很可能部分读者会认为在Startup事件之后,触发Activated事件;在触发Deactivated事件之后,触发DispatcherUnhandledException事件,这些类似的想法都是不正确的,都是由于没有认真查看图中箭头而产生的。
下面简单说明一下图1所包含的6个事件,它们是WPF应用程序生命周期中的主要事件。
Startup事件
在调用Application.Run()方法之后,主窗口显示之前,触发该事件。在该事件的处理程序中,开发人员可检测多个命令行参数。这些参数以数组形式存在,通过StartupEventArgs.Args属性即可访问参数数组。另外,可在Startup事件处理程序中添加显示用户界面,显示窗口等代码逻辑。例如,以下代码实现处理命令参数的功能:
void App_Startup(object sender, StartupEventArgs e)
{
for (int i = 0; i != e.Args.Length; ++i)
{
// 处理命令参数逻辑
...
}
}
Activated事件和Deactivated事件
当应用程序的窗口之一被激活时,触发该事件。激活是指加载应用程序并显示出窗口,或者从其他应用程序切换到当前应用程序。当应用程序被释放(deactivated)时,触发该事件。释放是指关闭应用程序的情况,或者从当前应用程序切换到其他应用程序。请看以下示例代码:
public partial class App : Application
{
bool isApplicationActive;
void App_Activated(object sender, EventArgs e)
{
// 设置变量值
this.isApplicationActive = true;
}
void App_Deactivated(object sender, EventArgs e)
{
// 设置变量值
this.isApplicationActive = false;
}
}
SessionEnding事件
当用户试图注销或者关闭电脑时,触发该事件(为了辨别是何种情况,可使用 SessionEndingCancelEventArgs.ReasonSessionEnding属性)。在该事件处理程序中,可实现如询问和显示有关信息,结束Windows会话等功能。请看以下示例代码:
void App_SessionEnding(object sender, SessionEndingCancelEventArgs e)
{
// 询问用户是否允许关闭会话
string msg = string.Format("{0}. End session?", e.ReasonSessionEnding);
MessageBoxResult result = MessageBox.Show(msg, "Session Ending", MessageBoxButton.YesNo);
// 根据选择确定是否终止会话
if (result == MessageBoxResult.No)
{
e.Cancel = true;
}
}
DispatcherUnhandledException事件
当应用程序发生任何未处理异常时,触发该事件。在该事件的处理程序中,可实现将异常记录到日志,继续或者中断应用程序等逻辑。请看如下示例代码,其使用消息窗口来显示异常消息:
void App_DispatcherUnhandledException ( object sender, DispatcherUnhandledExceptionEventArgs e)
{
string err = "Oops: " + e.Exception.Message);
MessageBox.Show(err, "Exception", MessageBoxButton.OK);
}
当关闭应用程序时,触发该事件。在该事件的处理程序中,开发人员可进行一些必要的最后处理,例如保存应用程序状态,释放资源等等。以下代码实现在应用程序退出时设置退出代码:
void App_Exit(object sender, ExitEventArgs e)
{
e.ApplicationExitCode = 52;
}
本篇文章详细介绍了WPF应用程序的核心对象Application。在读者今后的开发过程中将发现,本文所介绍的创建和访问Application对象,尤其是应用程序中的6大事件等内容是非常重要的知识,建议读者认真阅读,多多实践。