【问题标题】:Button is closing WindowsForm automatically按钮正在自动关闭 Windows 窗体
【发布时间】:2015-09-04 17:50:38
【问题描述】:

我有一个 WinForms 应用程序,只要用户点击取消按钮,它就会检查待处理的更改。如果有待处理的更改,我会提示用户查看他们是否确定要取消。如果他们这样做,我关闭表格。如果没有,我只是返回。但是,无论如何,表格正在关闭。经过一番调试,我意识到这是因为这个特定的按钮设置为表单的CancelButton,所以点击它导致表单关闭。为了验证,我删除了 CancelButton 属性,但行为仍然存在。

如何防止这种自动关闭?这是我的事件处理程序代码:

private void closeButton_Click(object sender, EventArgs e)
{
    DialogResult dr = DialogResult.Yes;

    if (changesMade)
    {
        dr = MessageBoxEx.Show(this, "Are you sure you wish to disregard the changes made?", "Changes Made", MessageBoxButtons.YesNo);
    }

    if (dr == DialogResult.Yes)
    {
        Close();
    }
    else
    {
        //TODO:
    }
}

在上面的代码中,只有在没有进行任何更改或用户选择忽略它们时,表单才应该关闭。我进行了更改,然后在对话框中单击“否”,但表单仍然关闭。有无按钮设置为表单的 CancelButton。

【问题讨论】:

  • 我建议您在 FormClosing event 而不是 ButtonClick 中进行检查。然后相应地设置e.Cancel。这样,无论关闭您的表单(无论是文件 -> 退出、右上角的 X 按钮等)都将始终提示未保存的更改。
  • 您是否使用断点和 F10 正确调试?不当行为的原因应该很容易找到。
  • @TobiasKnauss 是的,虽然我没有尝试过除此方法之外的任何其他方法。
  • 那么,尽管 close() 没有被调用,表单还是关闭了?如果是这样,则注释掉该函数中的整个代码并再次检查。如果仍然关闭,您需要寻找其他地方。
  • 您确定,您删除了“取消按钮”?您可以完全删除按钮并创建一个新按钮。由于我们看不到您的代码,因此很难进一步诊断。

标签: c# winforms


【解决方案1】:

只需将表单的属性DialogResult设置为枚举DialogResult.None

....
if (dr == DialogResult.Yes)
{
    Close();
}
else
{
    this.DialogResult = DialogResult.None;
}

或者简单地说:

if (dr != DialogResult.Yes)
   this.DialogResult = DialogResult.None;

表单自动关闭,因为按钮的属性 DialogResult 未在表单设计器中设置为 DialogResult.None。在这种情况下,WinForms 引擎获取该值并将其分配给整个表单的 DialogResult 属性,使其自动关闭。这通常用于表单的调用代码中,以区分确认按钮和取消按钮

在下面的示例中,假设 frmCustomers 上有两个按钮,一个将 DialogResult 属性设置为 DialogResult.OK,另一个设置为 DialogResult.Cancel。现在,如果用户点击你知道的 OK 按钮,在调用代码中如何处理新客户的输入

using(frmCustomers f = new frmCustomers())
{
    if(f.ShowDialog() == DialogResult.OK)
    {
       // Execute code to save a customer
    }
}

【讨论】:

  • 这很好用,谢谢!不过,我将使用 FormClosing 解决方案,因为我认为它使事情更具可读性。
【解决方案2】:

根据我的评论,这就是我最近为我写的一个内部工具所做的:

private void Form_FormClosing(object sender, FormClosingEventArgs e)
{
    e.Cancel = !PromptUnsavedChanges();
}

private bool PromptUnsavedChanges()
{
    if (HasFormChanged()) //checks if form is different from the DB
    {
        DialogResult dr = MessageBox.Show("You have unsaved changes. Would you like to save them?", "Unsaved Changes", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);

        if (dr == System.Windows.Forms.DialogResult.Yes)
            tsmiSave_Click(null, null); // Saves the data
        else if (dr == System.Windows.Forms.DialogResult.Cancel)
            return false; // Cancel the closure of the form, but don't save either
    }

    return true; // Close the form
}

从可读性的角度来看,逻辑可能会被清理掉,因为我在几个月后才看到它。但它确实有效。

有了这个,你只需在你的按钮点击事件中调用this.Close();。然后该事件处理提示并决定它是否应该实际关闭。

【讨论】:

  • 成功了,谢谢!我会使用这个解决方案,因为我发现它更具可读性。
  • 很高兴它对你有用。在调用提示之前,我可能会将其更改为在实际关闭事件中包含HasFormChanged,并且可能会反转返回值以删除!,但无论如何。
  • 我只是将我的方法更改为IgnoreChanges(),它直观地返回,是取消,否则没有。所以在 FormClosing 中我读到了e.Cancel = !IgnoreChanges()。我感觉合理!希望未来调试这个的我也这么认为。
  • 当心,FormClosing 的发生有多种原因。检查 FormClosingEventArgs 中的 CloseReason。
  • @Steve 很高兴知道,我不知道这一点。 Link to the CloseReason enum
猜你喜欢
  • 1970-01-01
  • 2022-12-11
  • 1970-01-01
  • 1970-01-01
  • 2010-12-12
  • 1970-01-01
  • 2013-06-05
  • 1970-01-01
相关资源
最近更新 更多