一、窗體類基本概念
對于WPF應用程序,在Visual Studio和Expression Blend中,自定義的窗體均繼承System.Windows.Window類。用戶通過窗口與 Windows Presentation Foundation (WPF) 獨立應用程序進行交互。 窗口的主要用途是承載可視化數據并使用戶可以與數據進行交互的內容。獨立 WPF 應用程序使用 Window 類來提供它們自己的窗口。在 WPF 中,可以使用代碼或 XAML 標記來實現窗口的外觀和行為。我們這里定義的窗體也由這兩部分組成:
1、 XAML文件,在這里面通常全部寫UI的東西,包括窗口的外觀,控件等。
<Window x:Class="WpfApp1.WindowThd" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="WindowThd" Height="300" Width="400"> <Grid> <StackPanel> <Label x:Name="lblHello">歡迎你光臨WPF的世界!</Label> <Button Name="btnThd" Click="btnThd_Click" >多線程同步測試</Button> <Button Name="btnAppBeginInvoke" Click="btnAppBeginInvoke_Click" >BeginInvoke 異步調用</Button> </StackPanel> </Grid> </Window>
2、窗口界面中的各種行為,則由后臺代碼文件決定。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; using System.Windows.Threading; namespace WpfApp1 { /// <summary> /// WindowThd.xaml 的交互邏輯 /// </summary> public partial class WindowThd : Window { public WindowThd() { InitializeComponent(); } private void ModifyUI() { // 模擬一些工作正在進行 Thread.Sleep(TimeSpan.FromSeconds(2)); //lblHello.Content = "歡迎你光臨WPF的世界,Dispatcher"; this.Dispatcher.Invoke(DispatcherPriority.Normal, (ThreadStart)delegate() { lblHello.Content = "歡迎你光臨WPF的世界,Dispatche 同步方法 !!"; }); } private void btnThd_Click(object sender, RoutedEventArgs e) { Thread thread = new Thread(ModifyUI); thread.Start(); } private void btnAppBeginInvoke_Click(object sender, RoutedEventArgs e) { new Thread(() => { Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => { Thread.Sleep(TimeSpan.FromSeconds(2)); this.lblHello.Content = "歡迎你光臨WPF的世界,Dispatche 異步方法!!"+ DateTime.Now.ToString(); })); }).Start(); } } }
二、窗體的生命周期
和所有類一樣,窗口也有生存期,在第一次實例化窗口時生存期開始,然后就可以顯示、激活和停用窗口,直到最終關閉窗口。
1、顯示窗體
- 構造函數
- Show()、ShowDialog()方法:Show()方法顯示非模態窗口,這意味著應用程序所運行的模式允許用戶在同一個應用程序中激活其他窗口。ShowDialog()方法顯示模態窗口,這個基本和WinForm類似
- 當初始化窗口時,將引發 SourceInitialized 事件并顯示窗口。
2、窗體的激活
在首次打開一個窗口時,它便成為活動窗口(除非是在 ShowActivated 設置為 false 的情況下顯示)。 活動窗口是當前正在捕獲用戶輸入(例如,鍵擊和鼠標單擊)的窗口。 當窗口變為活動窗口時,它會引發 Activated 事件。
當第一次打開窗口時,只有在引發了 Activated 事件之后,才會引發 Loaded 和 ContentRendered 事件。 記住這一點,在引發 ContentRendered 時,便可認為窗口已打開。
窗口變為活動窗口之后,用戶可以在同一個應用程序中激活其他窗口,還可以激活其他應用程序。 當這種情況出現時,當前的活動窗口將停用,并引發 Deactivated 事件。 同樣,當用戶選擇當前停用的窗口時,該窗口會再次變成活動窗口并引發 Activated。
3、關閉窗體
當用戶關閉窗口時,窗口的生命便開始走向終結。
- Close()方法:關閉窗體,并釋放窗體的資源
- Closing事件、Closed事件:關閉時、關閉后引發的事件,通常在Closing事件中提示用戶是否退出等信息。
4、窗體的生命周期。如下圖。
為了證實上面的結論,我們用下面的代碼進行測試:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; using System.Windows.Threading; namespace WpfApp1 { /// <summary> /// WindowThd.xaml 的交互邏輯 /// </summary> public partial class WindowThd : Window { public WindowThd() { this.Activated += WindowThd_Activated; this.Closing += WindowThd_Closing; this.ContentRendered += WindowThd_ContentRendered; this.Deactivated += WindowThd_Deactivated; this.Loaded += WindowThd_Loaded; this.Closed += WindowThd_Closed; this.Unloaded += WindowThd_Unloaded; this.SourceInitialized += WindowThd_SourceInitialized; InitializeComponent(); } void WindowThd_SourceInitialized(object sender, EventArgs e) { Console.WriteLine( "1---SourceInitialized!"); } void WindowThd_Unloaded(object sender, RoutedEventArgs e) { Console.WriteLine("Unloaded!"); } void WindowThd_Closed(object sender, EventArgs e) { Console.WriteLine("_Closed!"); } void WindowThd_Loaded(object sender, RoutedEventArgs e) { Console.WriteLine( "3---Loaded!"); } void WindowThd_Deactivated(object sender, EventArgs e) { Console.WriteLine("Deactivated!"); } void WindowThd_ContentRendered(object sender, EventArgs e) { Console.WriteLine("ContentRendered!"); } void WindowThd_Closing(object sender, System.ComponentModel.CancelEventArgs e) { Console.WriteLine("---Closing!"); } void WindowThd_Activated(object sender, EventArgs e) { Console.WriteLine("2---Activated!"); } private void ModifyUI() { // 模擬一些工作正在進行 Thread.Sleep(TimeSpan.FromSeconds(2)); //lblHello.Content = "歡迎你光臨WPF的世界,Dispatcher"; this.Dispatcher.Invoke(DispatcherPriority.Normal, (ThreadStart)delegate() { lblHello.Content = "歡迎你光臨WPF的世界,Dispatche 同步方法 !!"; }); } private void btnThd_Click(object sender, RoutedEventArgs e) { Thread thread = new Thread(ModifyUI); thread.Start(); } private void btnAppBeginInvoke_Click(object sender, RoutedEventArgs e) { new Thread(() => { Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => { Thread.Sleep(TimeSpan.FromSeconds(2)); this.lblHello.Content = "歡迎你光臨WPF的世界,Dispatche 異步方法!!"+ DateTime.Now.ToString(); })); }).Start(); } } }
打開窗體的事件執行順序為:如下圖。
三、關閉窗體的事件執行順序為:如下圖。
WPF窗體的詳細的屬性、方法、事件請參考MSDN,有很多的屬性、方法、事件與Windows應用程序中 System.Windows.Forms.Form類頗為相似。
文章列表