代码改变世界

Window Presentation Foundation系列(2)---探索Application类

2011-06-21 18:58  libiver  阅读(551)  评论(0编辑  收藏  举报

      声明:欢迎任何人和组织转载本blog中文章,但必须标记文章原始链接和作者信息。 

      本文链接:http://www.cnblogs.com/leezhm/archive/2011/06/21/2086308.html

      开拓进取的小乌龟------->cnBlogs 点滴点点滴滴 Blog

 

      一个WPF应用程序必须有一个Application对象实例或者它的子类实例,它代表了WPF的一个windows进程,它提供了WPF程序的生命周期,并且集成了ClickOnce部署功能。或者更明确地说,在WPF中应用程序就是System.Windows命名空间下Application类或者它的子类的一个实例。

 

      Application 是一个类,其中封装了 WPF 应用程序特有的功能,包括:

 

      Application 实现单一实例模式以提供对其窗口、属性和资源范围服务的共享访问。因此,对于每个 AppDomain,只能创建 Application 类的一个实例。可以使用标记、标记与代码隐藏或代码来实现 Application。如果 Application 是使用标记实现的(无论是标记还是标记与代码隐藏),则标记文件都必须配置为一个 Microsoft Build Engine (MSBuild) ApplicationDefinition 项。

     

      看下面一个最简单的WPF实例代码,如下:

   1:  using System;  
   2:  namespace SimpleWPFApp  
   3:  {  
   4:      class SimpleWPFApp  
   5:      {  
   6:          [STAThread]  
   7:          public static void Main()  
   8:          {  
   9:              System.Windows.Window wnd = new System.Windows.Window();  
  10:              wnd.Show();  
  11:                
  12:              System.Windows.Application app = new System.Windows.Application();  
  13:              app.Run();  
  14:          }  
  15:      }  
  16:  }

 

      在这里要注意的是,一定不要忘了再Main函数前面加上[STAThread],不然能编译通过,但是运行会出错的。

 

      [STATHread]:单线程套间(Single Threaded Apartment,STA)作为非托管组件对象模型(COM)的一部分,是用来管理COM间的调用。由于很多COM应用在.NET环境下如果使用多线程的话,会导致引用的COM不能正常运行,而如果不声明程序为STAThread的话,.NET就会自动使用多线程来提高效率,这样就会导致不可预知的后果。而MS的所有表现层框架,托管的以及非托管的,都以必须运行在初始化后的STA线程中。

 

      好了,下面说一下由.xaml文件和.xmal.cs文件(code-behind)经过Partial关键字编译连接起来的完整application类或者子类。

     

      首先是.xaml文件.

   1:  <Application x:Class="HelloWorldWPF.App"  
   2:               xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
   3:               xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
   4:               StartupUri="MainWindow.xaml">  
   5:      <Application.Resources>  
   6:             
   7:      </Application.Resources>  
   8:  </Application>

 

    下面是.xaml.cs文件

 

   1:  using System;  
   2:  using System.Collections.Generic;  
   3:  using System.Configuration;  
   4:  using System.Data;  
   5:  using System.Linq;  
   6:  using System.Windows;  
   7:  namespace HelloWorldWPF  
   8:  {  
   9:      /// <summary>  
  10:      /// Interaction logic for App.xaml  
  11:      /// </summary>  
  12:      public partial class App : Application  
  13:      {  
  14:      }  
  15:  }  

 

      当编译器遇到了partial关键字之后,会将.xaml和.xaml.cs文件组合编译连接成一个完整的app类(Application的子类)。在程序启动运行过程中,会出现一下步骤:

      1、创建一个Application类对象(其实是子类对象),并设置它的Application.Current属性。

      2、根据StartupUri属性指定的XAML文件,创建并显示UI。

      3、设置Application类对象(其实是Application的子类对象)的MainWindows属性。

      4、调用Application类对象(其实是Application的子类对象)的Run方法,并保持Application的运行,直到关闭主窗口。

 

补充两点:

      a、也可以通过响应Startup事件创建并显示一个UI。代码截图照片如下:

        b、通过将XAML文件的Build Action属性设置为ApplicationDefinition,改变Application类和Main函数的定义文件。

 

        Application事件介绍,事件是Application重要的组成部分,也是COM4编程语言的基础。可以将标准的Application的生命循环看成是一组事件的组合。总最开始的Startup,到最后的Exit。

 

  名称 说明
公共事件 Activated 当应用程序成为前台应用程序时发生。
公共事件 Deactivated 当应用程序停止作为前台应用程序时发生。
公共事件 DispatcherUnhandledException 在异常由应用程序引发但未进行处理时发生。
公共事件 Exit 恰好在应用程序关闭之前发生,且无法取消。
公共事件
公共事件 LoadCompleted 在已经加载、分析并开始呈现应用程序中的导航器导航到的内容时发生。
公共事件 SessionEnding 在用户通过注销或关闭操作系统而结束 Windows 会话时发生。
公共事件 Startup 在调用 Application 对象的 Run 方法时发生。

 

      结合一个实例来说明这些事件发生的顺便过程:

 

   1:  <Application x:Class="HelloWorldWPF.App"  
   2:               xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
   3:               xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
   4:               StartupUri="MainWindow.xaml"  
   5:               Startup="App_Startup"  
   6:               Activated="App_Activated"  
   7:               Deactivated="App_Deactivated"  
   8:               DispatcherUnhandledException="App_DispatcherUnhandledException"  
   9:               Exit="App_Exit">  
  10:      <Application.Resources>  
  11:             
  12:      </Application.Resources>  
  13:  </Application>  

 

   1:  using System;  
   2:  using System.Collections.Generic;  
   3:  using System.Configuration;  
   4:  using System.Data;  
   5:  using System.Linq;  
   6:  using System.Windows;  
   7:  using System.Diagnostics; // for Debug  
   8:  using System.Windows.Threading; // DispatcherUnhandledExceptionEventArgs  
   9:  namespace HelloWorldWPF  
  10:  {  
  11:      /// <summary>  
  12:      /// Interaction logic for App.xaml  
  13:      /// </summary>  
  14:      public partial class App : Application  
  15:      {  
  16:          // Startup Event  
  17:          void App_Startup(object sender, StartupEventArgs args)  
  18:          {  
  19:              Debug.WriteLine("Startup Event");  
  20:          }  
  21:          // Activated Event  
  22:          void App_Activated(object sender, EventArgs args)  
  23:          {  
  24:              Debug.WriteLine("Activated Event");  
  25:          }  
  26:          // Deactivated Event  
  27:          void App_Deactivated(object sender, EventArgs args)  
  28:          {  
  29:              Debug.WriteLine("Deactivated Event");  
  30:              throw new Exception("Dispatcher Unhandled Exception");  
  31:          }  
  32:          // DispatcherUnhandledException Event  
  33:          void App_DispatcherUnhandledException(object sender,  
  34:               DispatcherUnhandledExceptionEventArgs args)  
  35:          {  
  36:              // Process unhandled exception  
  37:              //  
  38:              // ......  
  39:              //  
  40:              Debug.WriteLine("DispatcherUnhandledException Event");  
  41:              // Prevent default unhandled exception processing  
  42:              args.Handled = true;  
  43:          }  
  44:          // Exit Event  
  45:          void App_Exit(object sender, ExitEventArgs args)  
  46:          {  
  47:              Debug.WriteLine("Exit Event");  
  48:          }  
  49:      }  
  50:  } 

 

    运行结果如下截图分析

      结果分析:

      1、Run触发Startup事件

      2、窗口呈现获得焦点触发 Activated事件

      3、我让窗口失去焦点触发Deactivated事件,但在Deactivated事件处理函数中自动抛出了一个没有被处理的异常,从而触发DispatcherUnhandledException事件

      4、再次让窗口获得焦点触发Activated事件

      5、关闭窗口,引发窗口失去焦点触发Deactivated事件,从而抛出未作处理的异常,触发DispatcherUnhandledException事件

      6、程序退出,触发Exit事件。程序结束生命期。

 

      好了,关于Application的其他服务,如ClickOnce,可以去查询MSDN,再次不做说明。