有朋友遇到這樣的一個問題,在WPF中,當Closing一個窗體時,將e.Cancel=true,然後再調用Hide()方法,以便隱藏窗口而不是關閉,但報異常了:“當Window Closing時不能設置Visibility,或調用Show(),Close(),Hide()方法”。OK,本隨筆將幫你解決該問題。
問題的關鍵在於不能再Closing方法中調用Close等,那麼只要我們知道用戶有意圖關閉窗體時,僅僅再Closing方法中取消關閉,然後在Closing緊接著的某個方法中調用Hide就OK了。為了體現這個“緊接著的某個方法”,讓我聯想到方法排隊,比如多個線程中的方法使用同一個對象時,這些方法將被排隊,否則異常。那麼就用Invoke來幫我們實現這個排隊就OK了。
假設我們的Window類型的win2時一個需要隱藏的窗口,企圖關閉該窗體時其會被隱藏,點擊主窗口上的btnShowWin2按鈕時窗體會再次被顯示。
我們實現一個Delegate,其代理的方法將異常窗體:
delegate void WillHide(); // private WillHide willHide; // this.willHide = new WillHide(this.HideWin2); // private void HideWin2() { this.win2.Hide(); }
當Closing時我們這樣:
void win2_Closing(object sender, CancelEventArgs e) { e.Cancel = true; Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, this.willHide); }Everything is OK!
整體的代碼:
Code using System; using System.Collections.Generic; using System.Linq; using System.Text; 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.Navigation; using System.Windows.Shapes; using System.ComponentModel; namespace ClosingDemo { /**//// <summary> /// Interaction logic for Window1.xaml /// </summary> public partial class Window1 : Window { delegate void WillHide(); private Window2 win2 = new Window2(); private WillHide willHide; public Window1() { InitializeComponent(); Test(); } private void HideWin2() { this.win2.Hide(); } private void Test() { App.Current.MainWindow = this; App.Current.ShutdownMode = ShutdownMode.OnMainWindowClose; this.willHide = new WillHide(this.HideWin2); this.win2.Closing += new CancelEventHandler(win2_Closing); this.btnShowWin2.Click += new RoutedEventHandler(btnShowWin2_Click); this.win2.Show(); } void btnShowWin2_Click(object sender, RoutedEventArgs e) { this.win2.Show(); } void win2_Closing(object sender, CancelEventArgs e) { e.Cancel = true; Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, this.willHide); } } }