WPF新建新窗口被关闭后,需要再次打开时的处理代码

关于closing事件的解释文章:自定义wpf关闭按钮触发的动作

基本的处理

如果你的窗口打开代码是这样的:

Window settingPage = new SettingWindow();
private void MoreSettingButton_Click(object sender, RoutedEventArgs e)
{
    settingPage.Show();
}

上面是按键后被触发的事件。

当打开的窗口被关闭后,你会发现,如果再次尝试打开,窗口会报错。

所以我们需要在子窗口的closing事件更改一下:
更改一下窗口loaded后执行的代码:

//重写关闭响应代码
this.Closing += SettingWindow_Closing;

处理事件内容改成这样:

private void SettingWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    e.Cancel = true;//取消这次关闭事件
    Hide();//隐藏窗口,以便下次调用show
}

这样,关闭事件只是一个隐藏窗口的事件,再次打开就不会报错了。

会额外引发的问题

由于需要在主窗口被关闭后,自动关闭其他窗口,所以主窗口的closing也被像下面这样重写了:

/// <summary>
/// 窗口关闭事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    foreach (Window win in App.Current.Windows)
    {
        if (win != this)
        {
            win.Close();
        }
    }
    e.Cancel = false;//正常关闭
}

本身在我们更改子窗口closing事件之前,这段代码是正常的,但是当我们想上面的代码那样处理后,由于关闭事件只是一个hide,所以会导致软件看起来像是被关闭了,实际还在运行的情况。

如何解决呢?我们可以新建一个class,放一个publish static的变量,来标记一下软件是不是被真正关闭了,最后主窗口的closig代码可以加一句更改这个状态的代码:

/// <summary>
/// 窗口关闭事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    Tools.Global.isMainWindowsClosed = true;
    foreach (Window win in App.Current.Windows)
    {
        if (win != this)
        {
            win.Close();
        }
    }
    e.Cancel = false;//正常关闭
}

子窗口的closing事件也需要相应的更改:

private void SettingWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    if (Tools.Global.isMainWindowsClosed)
    {
        //说明软件关了
        e.Cancel = false;
    }
    else
    {
        e.Cancel = true;//取消这次关闭事件
        Hide();//隐藏窗口,以便下次调用show
    }
}

至此,问题全部解决。

发表评论

您的电子邮箱地址不会被公开。