开发者

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();
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜