在WPF中,應用程式會經歷簡單的生命周期。在應用程式啟動後,將立即創建應用程式對象,在應用程式運行時觸發各種應用程式事件,你可以選擇監視其中的某些事件。最後,當釋放應用程式對象時,應用程式將結束。 一、創建Application對象 使用Application類的最簡單方式是手動創建它。下麵的示例演 ...
在WPF中,應用程式會經歷簡單的生命周期。在應用程式啟動後,將立即創建應用程式對象,在應用程式運行時觸發各種應用程式事件,你可以選擇監視其中的某些事件。最後,當釋放應用程式對象時,應用程式將結束。
一、創建Application對象
使用Application類的最簡單方式是手動創建它。下麵的示例演示了最小的程式:在應用程式入口(Main()方法)處創建名為MainWindow的視窗,並啟動一個新的應用程式:
在本質上,Visual Studio為Application類使用的模型與用於視窗的模型相同。起點是XAML模板,預設情況下該模板被命名為App.xaml,它看起來如下所示:
<Application x:Class="TestApplication.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="MainWindow.xaml"> </Application>
在“【WPF學習】第四章 載入和編譯XAML”介紹過,在XAML中使用Class特性創建派生自元素的類。因此,該類創建派生自Application的類,類名為TestApplication.App(TestApplication是項目名稱,也是在其中定義類的名稱空間,App是Visual Studio為派生自Application的自定義類使用的名稱。如果願意,可將類名該為任何更有趣的內容)。
Application標簽不僅創建自定義的應用程式類,還設置StartupUri屬性來確定代表主視窗的XAML文檔。因此,不需要時候用代碼顯示地實例化這個視窗——XAML解析器將自動完成這項工作。
與視窗一樣,應用程式類也在兩個獨立部分中進行定義,在編譯時融合到一起。自動生成的部分在項目中是不可見的,但該部分包含Main()入口出以啟動應用程式的代碼。該部分看起來如下所示:
public class App:Application { [STAThread] public static void Main() { Program app = new Program(); app.MainWindow = new MainWindow("MainWindow.xaml"); app.MainWindow.ShowDialog(); } }
如果確實對查看XAMl模板創建的自定義應用程式類感興趣,可查找位於項目目錄中的obj\Debug文件夾中的App.g.cs文件。
這裡給出的自動生成的代碼和手工編寫的自定義應用程式類代碼之間唯一的區別是,自動生成的類使用StartupUri屬性,而不是設置MainWindow屬性或把住窗體作為參數傳遞給Run()方法。只要使用相同的URI格式,就可以自由地使用這種方法創建自定義應用程式類。需要創建相對Uri對象,用於命名項目中的XAML文檔(該XAML文檔是編譯過的,並作為BAML資源被嵌入到應用程式的程式集中。該資源的名稱就是原來XAML文件的名稱。在上面的示例中,應用程式包含名為MainWindow.xaml的資源,該資源包含以編譯過的XAML文檔)。
自定義應用程式類的第二部分存儲在項目中諸如App.xaml.cs的文件中。該部分包含開發人員添加的處理事件的代碼,最初是空的:
public partial class App : Application { }
這個文件通過部分類技術和自動生成的應用程式代碼融合到一起。
三、應用程式的關閉方式
通常,只要還有視窗尚未關閉,Application類就保持應用程式處於有效狀態。如果這不是期望的行為,可調整Application.ShutdownMode屬性。如果手動實例化Application對象,就需要在調用Run()方法之前設置ShutdownMode屬性。如果使用App.xaml文件,那麼可在XAML文件中簡單設置ShutdownMode屬性。
對於關閉模式有三種選擇,如下表所示:
表 ShutdownMode枚舉值
例如,如果希望使用OnMainWindowClose方式,並且正在使用App.xaml文件,那麼需要添加如下內容:
<Application x:Class="TestApplication.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="MainWindow.xaml" ShutdownMode="OnMainWindowClose"> </Application>
不管選擇哪種關閉方法,總是可以使用Application.Shutdown()方法立即終止應用程式(當然,當調用Shutdown()方法時,應用程式未必立刻停止運行。調用Application.Shutdown()方法會導致Application.Run()方法立即返回,但仍可繼續運行Main()方法中的其他帶代碼或者響應Application.Exit事件)。
四、應用程式事件
最初,App.xaml.cs文件不包含任何代碼。儘管不需要代碼,但可添加代碼來處理應用程式事件。Application類提供了為數不多的非常有用的事件。下表給出了其中重要的幾個。
表 應用程式事件
處理事件時有兩種選擇:關聯事件處理程式或重寫相應的受保護方法。如果選擇處理應用程式事件,不需要使用委托代碼來關聯事件處理程式,而是可以使用App.xaml文件中的某個特性來關聯事件處理程式。例如,如果有如下事件處理程式:
private void Application_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e) { MessageBox.Show("An unhandled " + e.Exception.GetType().ToString() + " exception was caught and ignored."); e.Handled = true; }
可使用下麵的XAML來連接上面的事件處理程式:
<Application x:Class="TestApplication.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="MainWindow.xaml" ShutdownMode="OnMainWindowClose" DispatcherUnhandledException="Application_DispatcherUnhandledException"> <Application.Resources> </Application.Resources> </Application>
對於每個應用程式事件,可調用相應的方法來引發該事件。這個方法的名稱就是事件的名稱,只要在前面加上首碼On,因此Startup變成了OnStartup(),Exit變成OnExit(),等等。這種方式在.NET中是十分常見的。唯一的例外是DispatcherExceptionUnhandled事件——該事件沒有相應的OnDispatcherExceptionUnhandled()方法,所以始終需要使用事件處理程式。
下麵是一個自定義的應用程式類,它重寫了OnSessionEnding()方法, 並且如未設置了相應的標誌,該方法會阻止關閉系統和應用程式自身:
public partial class App : Application { private bool unsavedData = false; public bool UnSavedData { get { return unsavedData; } set { unsavedData = value; } } protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); unsavedData = true; } protected override void OnSessionEnding(SessionEndingCancelEventArgs e) { base.OnSessionEnding(e); if (unsavedData) { e.Cancel = true; MessageBox.Show( "The application attempted to be closed as a result of " + e.ReasonSessionEnding.ToString() + ".This is not allowed,as you have unsaved data."); } } }
當重寫應用程式方法時,最好首先調用基類的實現。通常,基類的實現知識引發相應的應用程式事件。
顯然,實現這一技術的更精妙的方法是,不使用消息框,而應顯示幾個確認對話框,讓用戶選擇是繼續(退出應用程式和Window系統)還是取消關閉。