【WPF學習】第二十六章 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系統)還是取消關閉。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM