在 WPF 中,若於 Closing 事件內設定 e.Cancel = true 並直接呼叫 Hide(),會拋出異常:「當 Window Closing 時不能設置 Visibility,或調用 Show/Close/Hide 方法」。這是因為視窗正處於關閉流程中,無法立即切換可見狀態。
關鍵在於「排隊」:在 Closing 取消關閉後,透過 Dispatcher.BeginInvoke 將 Hide 推送到 UI 執行緒的下一個優先順序,待關閉流程結束再執行隱藏。
Closing 事件中 e.Cancel = true 並 BeginInvoke 該委派。public partial class MainWindow : Window
{
private delegate void WillHide();
private WillHide _hideDelegate;
private SecondaryWindow _win2 = new SecondaryWindow();
public MainWindow()
{
InitializeComponent();
_hideDelegate = new WillHide(HideWin2);
_win2.Closing += Win2_Closing;
btnShowWin2.Click += (s, e) => _win2.Show();
_win2.Show();
}
private void HideWin2() => _win2.Hide();
private void Win2_Closing(object sender, CancelEventArgs e)
{
e.Cancel = true;
Dispatcher.BeginInvoke(DispatcherPriority.Normal, _hideDelegate);
}
}
此模式同樣適用於需在關閉時執行其他 UI 操作(如動畫、確認對話框)的情境。