How to detect that a Window has used up its "ShowDialog" call
In WPF you get to call ShowDialog
on a window exactly once. After that it is done for.
Seems kind of lame to me, but those are the rules. If you call ShowDialog
again you get this exception:
Can开发者_JAVA百科not set Visibility or call Show, ShowDialog, or WindowInteropHelper.EnsureHandle after a Window has closed
What I want to know is: How can I take a Window
(or UserControl
really) and check to see if it has had ShowDialog
called (so I know to new
up a different one before calling ShowDialog
again).
Something like this:
public void ShowListOfClients()
{
// | This is the method I want to write
// V
RefreshViewIfNeeded(_myWindowOrUserControlThatShowsAList);
FillWindowWithBusinessData(_myWindowOrUserControlThatShowsAList);
_myWindowOrUserControlThatShowsAList.ShowDialog();
}
NOTE: Clearly in the above example it would be easier to just create a new WindowOrUserControlThatShowsAList
every time I enter the method. But please consider the question more that the dumbed down example.
This isn't exclusive to ShowDialog(), Show() does it too. And no, there is no IsDisposed property to check. IsLoaded is only half a solution, it will be false for the 1st invocation as well.
First approach is to just make a dialog that can be re-shown:
public bool CloseAllowed { get; set; }
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
if (!CloseAllowed) {
this.Visibility = System.Windows.Visibility.Hidden;
e.Cancel = true;
}
}
The next one is to explicitly keep track of the health of the object reference:
private Window1 win = new Window1(); // say
private void button1_Click(object sender, RoutedEventArgs e) {
if (win == null) {
win = new Window1();
win.Closing += delegate { win = null; };
}
win.ShowDialog();
}
Well the dirty way to do it would be to catch the exception.
The clean way to do it would be to show a window with ShowDialog, and destroy (lose reference to, etc) the window when the function returns. The view should not be tightly coupled with the models (you are using MVVM right?) so creating new visual objects for each client view should not be an issue.
Easy way to deal with this problem without messing up with the Closing event :
public partial class MainWindow
{
private SomeCustomWindow _someCustomWindow;
public MainWindow()
{
InitializeComponent();
}
private void OnOpenCustomWindowButtonClick(object sender, RoutedEventArgs e)
{
if (_someCustomWindow != null)
_someCustomWindow.Close();
_someCustomWindow = new SomeCustomWindow();
_someCustomWindow.ShowDialog();
}
private void OnWindowClosing(object sender, CancelEventArgs e)
{
if (_someCustomWindow!= null)
_someCustomWindow.Close();
}
}
精彩评论