博客園WPF Application類
所有的WPF程序,都是由Application類實例創建,該類負責打開當前應用程序和窗體,並且決定如何關閉應用程序等。Application類的主要功能可以簡單總結以下幾點:
1、保持主線程
使用Application後,只要有窗體沒有退出,則應用程序不會退出,他會重新定義出新的主窗體,只有所有的窗體都關閉,Appliction才決定是否退出應用程序。Application起到管理所有窗體的作用。看如下代碼:
class Program { [STAThread()] static void Main(string[] args) { Application app= new Application(); Window win = new Window(); app.Run(win); } }
效果會開啟一個應用程序,假如我們不使用Application ,代碼如下:
class Program { [STAThread()] static void Main(string[] args) { Window win = new Window(); win.ShowDialog(); } }
感覺效果上,沒有任何差別,但實際上,兩個完全不一樣,假如我們定義一個MainWindow的類,在這個類中放一個按鈕,彈出另外一個窗體,效果會怎麽樣呢,看如下代碼:
class Program { [STAThread()] static void Main(string[] args) { Application app = new Application(); Window win = new Window(); win.MouseDown += Win_MouseDown; win.ShowDialog(); app.Run(); } private static voidWin_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e) { Window win = new Window(); win.Show(); } }
當我們關閉父窗體,應用程序並沒有退出。如果將Application去掉,編寫以下代碼:
class Program { [STAThread()] static void Main(string[] args) { Window win = new Window(); win.MouseDown += Win_MouseDown; win.ShowDialog(); } private static void Win_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e) { Window win = new Window(); win.Show(); } }
我們關閉父窗體,則整個應用程序退出。
這說明Applicationn在有任何一個窗體存在的情況下,能保證軟件的持續運行,保證主線程不退出。
2、啟動xaml窗體
我們可以通過指定StartupUri ,來告訴Appliction如何啟動窗體,其代碼如下:
class Program { [STAThread()] static void Main(string[] args) { Application app = new Application(); app.StartupUri = new Uri("MainWindow.xaml",System.UriKind.Relative); app.Run(); } }
所以,我們在編寫wpf應用程序的時候,會有一個App.xaml的文件,其就是Appliction的定義,看看其代碼如下:
<Application x:Class="Ani.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:Ani" StartupUri="MainWindow.xaml"> </Application>
也是通過指定StartupUri屬性,啟動窗體,那Application是如何啟動的呢,我們可以在當前程序的obj目錄下面,可以看到App.g.cs文件,打開裏面的代碼,可以看到如下代碼:
public partial class App : System.Windows.Application { /// <summary> /// InitializeComponent /// </summary> [System.Diagnostics.DebuggerNonUserCodeAttribute()] [System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")] public void InitializeComponent() { #line 5 "..\..\App.xaml" this.StartupUri = new System.Uri("MainWindow.xaml", System.UriKind.Relative); #line default #line hidden } /// <summary> /// Application Entry Point. /// </summary> [System.STAThreadAttribute()] [System.Diagnostics.DebuggerNonUserCodeAttribute()] [System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")] public static void Main() { Ani.App app = new Ani.App(); app.InitializeComponent(); app.Run(); } }
所以WPF應用程序會主動給我們創建一個主程序App.cs和一個App.xaml文件,但App.cs並沒有對編輯器放開,我們只需要編輯App.xaml文件即可
3、應用程序的關閉方式
Application裏面有一個ShudonwModel屬性,這個屬性是一個枚舉對象,用於指定當前應用程序的關閉方式,其有三個選項。
OnLastWindowClos e | 默認行為,只要至少一個窗體存在,應用程序就保持運行狀態,應用程序會根據窗體的開啟循序,自動指定主窗體。 |
OnMainWindowClose | 這個是指,只要主窗體(最新開啟)存在,應用程序才保持運行狀態 |
OnExplicaitShutdown | 除非調用Appliction.Shutdown()方法,否則應用程序不會結束。 |
代碼如下:
<Application x:Class="Ani.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:Ani" StartupUri="MainWindow.xaml" ShutdownMode="OnLastWindowClose"> </Application>
4、應用程序的事件
Application提供了為數不多幾個事件,但這幾個事件非常有用。
4.1 Startup
這個事件在調用Appliction.Run()方法之前,並且在主窗體顯示之前發生,可以使用這個事件讀取當前應用程序的命令行參數,而且還示意使用該事件指定StartupUri 屬性
4.2 Exit
事件發生在應用程序關閉時(不管是什麽原因關閉),並在Run()方法返回之前發生,但此時已經不能取消關閉,但是可以通過Run()方法重新啟動程序。
4.3 SessionEnding
該事件在window對話結束時發生,例如,當用戶關閉或者註銷計算機時,我們來確定是否關閉應用程序,我們可以設置SessionEndingEventArgsCancel屬性設置為true來取消關閉應用程序。否則,當事件處理結束後,WPF會調用Application.Shutdown()方法關閉事件。
4.4 Activated
激活當前應用程序的時候調用,當從另外一個應用程序切換到當前應用程序的時候調用,當第一次顯示窗體的時候調用
4.5 Deactived
當取消激活應用程序中的窗體的時候,觸發該事件。當切換到另外一個應用程序時,調用該事件。
4.6 DispatcherUnhandledException
當應用程序中的任何位置,只要發生未處理的異常,就會發生該事件,使用該事件來記錄重要錯誤。
5、處理命令行參數
為了處理命令行參數,需要響應Application.Startup事件。命令行參數以參數通過StartupEventArgs.Args屬性作為字符串數組提供。
public partial class App : Application { private void Application_Startup(object sender, StartupEventArgs e) { if (e.Args.Length > 0) { foreach (var arg in e.Args) { Console.WriteLine(arg); } } } }
6、負責窗體之間的交互
我們可以通過Application的current屬性,獲取當前的Appliction,也可以通過Application的MainWindow屬性,獲取當前的主窗體,所以,可以通過Application訪問當前的Application裏面的數據,同時可以訪問主窗體的數據。我們可以將一些全局信息,定義在Application中,那麽應用程序在任意位置都可以訪問,實現所有窗體互相交互,如下代碼:
public partial class App : Application { public List<string> Globals = new List<string>(); private void Application_Startup(object sender, StartupEventArgs e) { ((App)Application.Current).Globals.Add("hello"); } }
博客園WPF Application類