Application對象windows
當一個WPF應用程序啓動時,首先會實例化一個全局惟一的Application對象,相似於WinForm下的Application類,用於控制整個應用程序,該類將用於追蹤應用程序打開的窗口。在應用程序打開或關閉的時候可以觸發相應的事件。數組
建立Application對象app
手動建立Application應用程序對象過程:ide
一、 使用VS建立WPF應用程序,命名爲WPFDemo。而後手動清除App.xaml文件。函數
二、 添加Startup.cs類,並添加程序代碼。以下:this
using System.Windows;//添加windows命名空間
namespace WPFDemo
{
public class Startup
{
[STAThread]
public static void Main()
{
Application app = new Application();//建立application對象
MainWindow win = new MainWindow();//實例化窗口對象,做爲應用程序主窗口
win.Title = "應用程序主窗口";//指定應用程序窗口標題
app.Run(win);//調用Run方法開始運行應用程序
}
}
}
三、 F5啓動應用程序。spa
關閉應用程序操作系統
Application類提供了一個ShutdownMode的枚舉屬性值,能夠供開發人員指定應用程序的關閉模式。開發人員能夠在Application的OnStartup事件爲這個屬性賦值,也能夠在XAML文件中設置這個屬性。命令行
ShutdownModel 枚舉值調試
枚舉值 |
說明 |
OnLastWindoClose |
當最後一個窗口關閉或在調用Application.Shutdown方法時,應用程序將關閉。 |
OnMainWindowClose |
主窗口關閉或者調用Application.Shutdow方法時,應用程序關閉。 |
OnExplicitShutdown |
即便全部窗口都被關閉,應用程序也不會終止。這個方法適用於一些長時間運行後臺任務的場合。當顯式調用Application.Shutdown方法後,應用程序纔會退出。 |
Application類OnStartup事件中設置ShutdownMode枚舉值。
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
this.ShutdownMode = ShutdownMode.OnMainWindowClose;
}
App.xaml中指定的ShutdownMode值
<Application x:Class="WPFDemo.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPFDemo"
StartupUri="MainWindow.xaml"
ShutdownMode="OnLastWindowClose">
<Application.Resources>
</Application.Resources>
</Application>
應用程序事件
應用程序執行將會按照順序觸發下列事件。
一、 Startup:應用程序啓動事件。
二、 Activated:當應用程序的頂層窗口被激活時觸發此事件。
三、 Deactiveated:當應用程序的頂層窗口失去焦點時觸發此事件。
四、 DispatherUnhandledException:當應用程序的產生未處理異常時觸發此事件。
五、 SessionEnding:當Windows會話被終止時觸發此事件,例如用戶註銷或關閉計算機。
六、 Exit:當應用程序由於某種緣由而被關閉時觸發此事件。
Startup 應用程序啓動事件
該事件在Run方法被調用後觸發,這個事件一般用於放置應用程序範圍的初始化信息。獲取和設置應用程序範圍的配置,處理命令行參數等。該事件提供了StartupEventArgs類型的參數,包含了命令行參數信息。
Startup事件能夠完成下列任務。
(1)、處理命令行參數。
(2)、打開主窗口。
(3)、初始化應用程序範圍的資源。
(4)、初始化應用程序範圍的屬性。
Startup事件,首先在App.xaml文件中,去掉StartupUri屬性,關聯Startup事件處理器。
<Application x:Class="WPFDemo.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPFDemo"
Startup="Application_Startup">
<Application.Resources>
</Application.Resources>
</Application>
接下來在 App.xaml.cs 文件中添加下列事件處理器
private void Application_Startup(object sender, StartupEventArgs e)
{
MainWindow win = new WPFDemo.MainWindow();
win.Show();
}
在實際項目開發中,OnStartup中的代碼能夠很是複雜,能夠讀取應用程序資源或讀取應用程序設置中讀取配置信息,配置參數等。
Activated和Deactiveated事件
應用程序的激活與Window的激活和取消激活相似,但應用程序的激活一般是指全局應用程序的激活,一般發生在以下狀況下:
一、 應用程序打開第一個窗口。
二、 用戶使用Alt+Tab組合件或者使用任務管理器切換到該應用程序。
三、 用戶單擊應用程序中一個窗口的任務欄按鈕。
與窗口不一樣的是,一旦應用程序激活,在應用程序停用前都不會再次引起Activated事件。
在上面示例中新增一個名爲Window2.xaml的窗口。並修改OnStartup事件處理器的代碼,使其啓動時可以顯示兩個窗口。
private void Application_Startup(object sender, StartupEventArgs e)
{
MainWindow win = new WPFDemo.MainWindow();
win.Title = "經過OnStartup事件啓動的主窗口";
win.Show();
Window2 win2 = new Window2();
win2.Title = "經過OnStartup時間啓動的第二個窗口";
win.Show();
}
//重載OnActivated事件,在窗體被激活時觸發。 protected override void OnActivated(EventArgs e) { System.Diagnostics.Debug.Write("當前應用程序被激活"); foreach (Window win in Windows) { if (win.IsActive) { System.Diagnostics.Debug.WriteLine("當前的活動窗口是:" + win.Title); } } base.OnActivated(e); }
//重載OnDeactivated事件,在窗體被取消激活時觸發。
protected override void OnDeactivated(EventArgs e)
{
base.OnDeactivated(e);
System.Diagnostics.Debug.WriteLine("當前應用程序中止激活");
}
DispatherUnhandledException事件
DispatcherUnhandledException 給開發人員一個處理應用程序爲處理的異常的地方。在window1.xaml.cs 的構造函數中拋出一個異常。
public Window1()
{
InitializeComponent();
throw new Exception("演示DispatherUnhandledException的做用,這裏拋出一個異常");
}
而後在App.xaml中添加對DispatherUnhandledException屬性的賦值,最後在App.xaml.cs中添加一些代碼來顯示一個自定義的錯誤窗口。
private void Application_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
string err = "異常信息:" + e.Exception.Message.ToString();
MessageBox.Show(err);
e.Handled = true;
}
運行應用程序將會彈出下面對話框
SessionEnding事件 – 註銷或關閉系統
當Windows操做系統的會話終止時,則會觸發SessionEnding事件。SessionEnding事件有一個SessionEndingCancelEventArgs類型的參數,該參數有一下Cancel布爾屬性,當設置爲true時,將會取消windows的會話終止行爲。除此以外,還可使用ReasonSessionEnding枚舉類型的屬性,來檢測終止會話的類型,該屬性有下面兩個值:
一、 Logoff :會話正在結束的緣由是用戶正在註銷。
二、 Shutdown : 會話正在結束的緣由是用戶正在關閉Windows。
下面演示如何使用SessionEnding事件,當windows應用程序終止時,彈出一個對話框窗口提示用戶進行選擇。
App.xaml 文件制定SessionEnding事件
<Application x:Class="WPFDemo.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPFDemo"
Startup="Application_Startup"
SessionEnding="Application_SessionEnding"
>
<Application.Resources>
</Application.Resources>
</Application>
在App.xaml.cs文件中添加以下代碼
private void Application_SessionEnding(object sender, SessionEndingCancelEventArgs e)
{
//詢問用戶是否容許終止會話
string msg = string.Format("{0} 是否要終止Windows會話?", e.ReasonSessionEnding);
MessageBoxResult result = MessageBox.Show(msg, "Session Ending", MessageBoxButton.YesNo);
if (result == MessageBoxResult.No)
{//若是點擊yes,容許終止,不然禁止終止會話
e.Cancel = true;
}
}
運行應用程序,當windows終止會話時,應用程序會彈出以下圖的對話框,若是用戶點擊「取消」按鈕,則會取消終止Windows會話。
Exit事件
當應用程序退出時,將觸發Exit事件。下面演示應用程序退出時,向用戶隔離區寫入應用程序日誌和應用程序狀態。首先在App.xaml代碼中添加事件處理器聲明
App.xaml文件
<Application x:Class="WPFDemo.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPFDemo"
Startup="Application_Startup" DispatcherUnhandledException="Application_DispatcherUnhandledException"
SessionEnding="Application_SessionEnding"
Exit="Application_Exit"
>
<Application.Resources>
</Application.Resources>
</Application>
在App.xaml.cs文件中添加以下代碼
/// <summary>
/// 應用程序退出標誌
/// </summary>
public enum ApplicationExitCode
{
Success = 0,
Failure = 1,
CantWriteToApplicationLog = 2,
CantPersistApplicationState = 3
}
/// <summary>
/// 應用程序退出
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Application_Exit(object sender, ExitEventArgs e)
{
try
{
if (e.ApplicationExitCode == (int)ApplicationExitCode.Success)
{
WriteApplicationLogEntry("Failure", e.ApplicationExitCode);
}
else
{
WriteApplicationLogEntry("Success", e.ApplicationExitCode);
}
}
catch
{
//寫入應用程序失敗時,更新退出代碼已反映出寫入失敗
e.ApplicationExitCode = (int)ApplicationExitCode.CantWriteToApplicationLog;
}
//保存應用程序狀態
try
{
PersistApplicationState();
}
catch
{
//寫入應用程序失敗時,更新退出代碼已反映出寫入失敗
e.ApplicationExitCode = (int)ApplicationExitCode.CantPersistApplicationState;
}
}
/// <summary>
/// 記錄應用程序日誌
/// </summary>
/// <param name="message"></param>
/// <param name="exitCode"></param>
private void WriteApplicationLogEntry(string message, int exitCode)
{
//寫入日誌項到用戶隔離存儲區
IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForAssembly();
using (Stream stream = new IsolatedStorageFileStream("log.txt", FileMode.Append, FileAccess.Write, store))
{
using (StreamWriter writer = new StreamWriter(stream))
{
string entry = string.Format("{0}:{1} - {2}", message, exitCode, DateTime.Now);
writer.WriteLine(entry);
}
}
}
/// <summary>
/// 記錄應用程序狀態日誌
/// </summary>
private void PersistApplicationState()
{
//保存應用程序狀態到用戶隔離存儲區
IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForAssembly();
using (Stream stream = new IsolatedStorageFileStream("state.txt", FileMode.Create, store))
using (StreamWriter writer = new StreamWriter(stream))
{
//能夠在這裏更改成自定義的保存應用程序狀態的程序代碼
foreach (DictionaryEntry entry in this.Properties)
{
writer.WriteLine(entry.Value);
}
}
}
上面代碼中,首先定義一個推出的枚舉類型。在應用程序Exit事件觸發,根據不一樣的推出寫入不一樣的信息到用戶的隔離存儲區。一般在Exit事件中保存應用程序的配置信息,當應用程序啓動時能夠在Startup加載配置信息。
Application類的任務
處理命令行參數
在WPF應用程序中,可使用兩種方法來處理命令行參數。一種是經過Environment對象的靜態GetCommandLineArgs方法,另外一種是經過相應Application類的Startup事件。該事件提供了SartupEventArgs類型的參數,該參數中包含了從命令行提示符或桌面傳遞的命令行參數。
使用Startup中 StartupEventArgs獲取命令行參數
在App.xaml中指定Startup=」Application_Startup」事件,並在App.xaml.cs Startup事件中添加下列代碼
private void Application_Startup(object sender, StartupEventArgs e)
{
//該bool值將從命令行參數中獲取。若是制定了特定的命令行參數,則將該bool值設置爲true;
bool startMinimized = false;
//命令行參數是一個字符串數組類型,遍歷參數數組,尋找特定的命令行參數。
for (int i = 0; i < e.Args.Length; i++)
{
if (e.Args[i] == "/StartMinimized")
{
startMinimized = true;
}
}
//建立應用程序主窗口,若是指定了命令行參數,則最小化運行應用程序。並在窗口顯示第一個命令行參數。
Window1 win = new Window1();
if (startMinimized)
{
win.WindowState = WindowState.Minimized;
win.Content = "當前命令行參數" + e.Args[0];
}
win.Show();
}
下面在項目中設置命令行參數來調試應用程序。首先在項目名稱點擊【右鍵】選擇【屬性】【調試】而後再命令行參數設置/StartMinimized。(以下圖)而後啓動應用程序發現應用程序以最小化方式運行,而且在窗體中顯示「當前命令行參數/StartMinimized」
也可使用CMD命令加參數的方式啓動應用程序(以下圖):
一、 打開CMD命令窗口。
二、 使用cd命令進入應用程序所在的文件夾。 命令: cd 目錄名稱
三、 而後執行exe應用程序,並指定參數。命令:WPFDemo.exe /StartMinimized
使用Environment的GetCommandLineArgs方法獲取命令行參數
只須要將上面代碼中獲取參數部分替換爲
string[] args = Environment.GetCommandLineArgs();
完整代碼以下:
private void Application_Startup(object sender, StartupEventArgs e) { //該bool值將從命令行參數中獲取。若是制定了特定的命令行參數,則將該bool值設置爲true; bool startMinimized = false; ///使用Environment的GetCommandLineArgs方法獲取命令行參數 string[] args = Environment.GetCommandLineArgs(); //命令行參數是一個字符串數組類型,遍歷參數數組,尋找特定的命令行參數。 foreach (string arge in args) { if (arge == "/StartMinimized") { startMinimized = true; } }
//建立應用程序主窗口,若是指定了命令行參數,則最小化運行應用程序。並在窗口顯示第一個命令行參數。 Window2 win = new Window2(); if (startMinimized) { win.WindowState = WindowState.Minimized; win.Content = "當前命令行參數" + e.Args[0]; } win.Show(); }
單實例應用程序
一個WPF應用程序能夠被打開屢次,併產生多個進程。在不少場景下只能容許運行一個應用程序。下面提供兩種方式建立單實例的應用程序
一、 使用System.Threading命名空間中的Mutex,稱爲同步基元或者互斥元。
二、 使用windowsFormsApplicationBase類實現單實例應用程序。
使用System.Threading命名空間的Mutex建立單實例應用程序。
一、 引用System.Threading命名空間,定義Mutex對象。
二、 重載Startup方法
三、 運行兩個WPF應用程序會彈出「已存在一個應用程序實例」對話框,並關閉當前應用程序。
Mutex mutex;
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
string mutexName = "WPFDemo";
bool CreatedNew;
mutex = new Mutex(true, mutexName, out CreatedNew);
if (!CreatedNew)//若是有存在的實例,則關閉當前實例
{
MessageBox.Show("已存在一個應用程序實例");
Shutdown();
}
}
使用windowsFormsApplicationBase實現單實例應用程序。
一、 添加Microsoft.VisualBasic.dll程序集的引用。
二、 新建SingleApplicationBase類,並添加
Microsoft.VisualBasic 和 Microsoft.VisualBasic.ApplicationServices命名空間。
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
//添加命名空間
using Microsoft.VisualBasic;
using Microsoft.VisualBasic.ApplicationServices;
namespace SingleInstanceWithCommunication
{
public class SingleApplicationBase : WindowsFormsApplicationBase
{
public SingleApplicationBase()
{
this.IsSingleInstance = true; //設置爲容許單例模式
}
private App wpfApp;
protected override bool OnStartup(StartupEventArgs eventArgs)
{
wpfApp = new App();
wpfApp.Run();
return false;
}
//當有其餘應用程序實例化時,則出發此事件,將WPF應用程序中顯示一個新的窗口
protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs)
{
base.OnStartupNextInstance(eventArgs);
Console.WriteLine("啓動實例");
}
}
}
三、 右鍵選擇App.xaml頁面的屬性,更改生成操做位Page。
四、 而後再App.xaml.cs中添加代碼。重載Onstartup事件,設置啓動頁面,而後建立應用程序啓動的Main方法。
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
MainWindow win = new SingleInstanceWithCommunication.MainWindow();
this.MainWindow = win;
win.Show();
}
[STAThread]
public static void Main(string[] args)
{
SingleApplicationBase sab = new SingleApplicationBase();
sab.Run(args);
}
五、屢次啓動應用程序,發現同時只能運行一個實例。