如何在WinForms应用程序中关闭表单时防止多次确认对话框?

问题描述 投票:0回答:1

我有一个 WinForms 应用程序,我需要在关闭表单时显示一个确认对话框,并且它应该关闭整个应用程序。但是,关闭应用程序时会多次出现确认对话框,这不是所需的行为。

protected override void OnFormClosing(FormClosingEventArgs e)
{
    if (e.CloseReason == CloseReason.UserClosing)
    {
        DialogResult result = MessageBox.Show("Are you sure you want to close the application?", "Confirm Exit", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

        if (result == DialogResult.No)
        {
            e.Cancel = true; // Cancel the form closing
            return;
        }
        else
        {
            // Close the entire application
            Application.Exit();
        }
    }
}

关闭此应用程序时会出现两个或多个此对话框

  • 如何确保关闭表单时确认对话框只显示一次?

  • 是否有更有效的方法来处理关闭多个表单并仅显示一次确认对话框?

  • 确认对话框旨在确认用户是否要关闭整个应用程序。

  • 应用程序中还打开了其他表单,这些表单也应在主表单关闭时关闭。

c# .net winforms windows-forms-designer
1个回答
0
投票

仔细阅读您的代码和项目符号项目,我的理解是您有一个应用程序的主表单,并且有可以同时和非模式显示的“多个表单”,其可见性可以根据用户认为合适的方式来来去去。一般情况下的最小示例可能如下所示:

multiple forms


因此,您可以尝试简化

MainForm.OnFormClosing()
,它将由代码中任何位置的“任何”
Application.Exit
调用调用。不需要在这里检查
CloseReason
,通过在
this
中传递
Show(this)
,可以确保子窗体在 Z 顺序中保持在主窗体的顶部,并在
MainForm
时进行处理确实如此(调试写入将证明)。

public partial class MainForm : Form
{
    public MainForm()
    {
        InitializeComponent();            
        buttonShowFormA.Click += (sender, e) => _formA.Show(this);
        buttonShowFormB.Click += (sender, e) => _formB.Show(this);
        _formA.VisibleChanged += (sender, e) => buttonShowFormA.Enabled = !_formA.Visible;
        _formB.VisibleChanged += (sender, e) => buttonShowFormB.Enabled = !_formB.Visible;
#if DEBUG
        _formA.Disposed += (sender, e) => Debug.WriteLine("Disposing Form A");
        _formB.Disposed += (sender, e) => Debug.WriteLine("Disposing Form B");
#endif
    }
    ChildFormA _formA = new() { StartPosition = FormStartPosition.Manual };
    ChildFormB _formB = new () { StartPosition = FormStartPosition.Manual };
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        _formA.Location = new() { X = Right + 10, Y = Top };
        _formB.Location = new() { X = Right + 10, Y = Top + _formA.Height + 10 };
        _formA.Show(this);
        _formB.Show(this);
    }
    protected override void OnFormClosing(FormClosingEventArgs e)
    {
        base.OnFormClosing(e);
        DialogResult result = MessageBox.Show("Are you sure you want to close the application?", "Confirm Exit", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

        if (result == DialogResult.No)
        {
            e.Cancel = true; // Cancel the form closing
            return;
        }
    }
}

CloseReason
在子窗体中很重要,因为我们需要更改窗体关闭时窗口
Form
所处理的
Handle
行为(当能够循环子窗体时,这是一个大问题)需要反复形成可见性)。

处理此问题的常见方法是取消

Close
并将其转换为
Hide
形式,只有当
Close
是应用程序退出或其他与系统相关的关闭时才允许
CloseReason
继续进行。

public partial class ChildFormA : Form
{
    public ChildFormA()
    {
        InitializeComponent();
        buttonClose.Click += (sender, e) => Close();
        buttonExit.Click += (sender, e) => Application.Exit();
    }
    protected override void OnFormClosing(FormClosingEventArgs e)
    {
        base.OnFormClosing(e);
        switch (e.CloseReason)
        {
            case CloseReason.UserClosing:
                e.Cancel = true;
                Hide();
                break;
        }
    }
}

这个基本示例应该能够触及您问题中的大部分要点。

© www.soinside.com 2019 - 2024. All rights reserved.