關於Window.ShowDialog()方法,有一個常見的容易犯的錯誤。下面給出這個錯誤的例子:
DemoA:錯誤的例子
1. 在WPF項目中,建立一個Windows:DialogWindow
DialogWindow.xaml
<Window x:Class="DemoA.DialogWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="I am a dialog window" Height="200" Width="300"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="140" /> <RowDefinition Height="60" /> </Grid.RowDefinitions> <Label Grid.Row="0" Margin="12" Content="Hello!" /> <WrapPanel Grid.Row="1" Margin="0" HorizontalAlignment="Center"> <Button Content="OK" Margin="5,0,5,0" Width="60" /> <Button Content="Cancel" Margin="5,0,5,0" Width="60" Click="ButtonCancelOnClick"/> </WrapPanel> </Grid></Window>
DialogWindow.xaml.cs
using System.Windows;namespace DemoA{ /// <summary> /// Interaction logic for DialogWindow.xaml /// </summary> public partial class DialogWindow : Window { public DialogWindow() { InitializeComponent(); } private void ButtonCancelOnClick(object sender, RoutedEventArgs e) { this.Close(); } }}
然後在MainWindow裡面去調用它:
MainWindow.xaml
<Window x:Class="DemoA.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Grid> <Button Width="Auto" Height="Auto" Content="Show dialog" Click="ButtonClick" /> </Grid></Window>
MainWindow.xaml.cs
using System.Windows;namespace DemoA{ /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { private DialogWindow dialogWindow = new DialogWindow(); public MainWindow() { this.InitializeComponent(); } private void ButtonClick(object sender, RoutedEventArgs e) { dialogWindow.ShowDialog(); } }}
這個例子似乎非常尋常。看出它有什麼問題了嗎?如果您看出問題來了,那麼本文對您來說純屬浪費時間,請移步其它文章,謝謝。
好,下面我們運行它。運行時,點擊MainWindow視窗的按鈕,第一次點擊,彈出了DialogWindow對話方塊,沒什麼問題。點擊“Cancel”按鈕關閉DialogWindow對話方塊,再次點擊MainWindow視窗的按鈕,這時候問題出現了,拋出了以下異常:
An unhandled exception of type 'System.InvalidOperationException' occurred in PresentationFramework.dllAdditional information: Cannot set Visibility or call Show, ShowDialog, or WindowInteropHelper.EnsureHandle after a Window has closed.
如何解決這個問題呢?解決方案如下:DemoB
DialogWindow.xaml.cs
using System.Windows;namespace DemoB{ /// <summary> /// Interaction logic for DialogWindow.xaml /// </summary> public partial class DialogWindow : Window { private static DialogWindow staticInstance = null; public DialogWindow() { this.InitializeComponent(); this.Closed += WindowOnClosed; } public static DialogWindow GetInstance() { if (staticInstance == null) { staticInstance = new DialogWindow(); } return staticInstance; } private void ButtonCancelOnClick(object sender, RoutedEventArgs e) { this.Close(); } private void WindowOnClosed(object sender, System.EventArgs e) { staticInstance = null; } }}
MainWindow.xaml.cs
using System.Windows;namespace DemoB{ /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { this.InitializeComponent(); } private void ButtonClick(object sender, RoutedEventArgs e) { DialogWindow.GetInstance().ShowDialog(); } }}
這樣,每次調用Window.ShowDialog()方法的時候,都建立了一個新的DialogWindow執行個體,所以問題得以解決。
參考:
同樣的疑問,在StackOverflow上的討論如下:
《WPF: Cannot reuse window after it has been closed》
http://stackoverflow.com/questions/3568233/wpf-cannot-reuse-window-after-it-has-been-closed