【问题标题】:How do I keep the user from exiting the program if there are any unsaved changes on the form?如果表单上有任何未保存的更改,如何防止用户退出程序?
【发布时间】:2019-05-10 20:32:22
【问题描述】:

我有一个带有几个 numericUpDown 控件的 Winforms,我希望程序在用户单击表单上的退出按钮时发出警告,如果他们有未保存的更改,如果没有未保存的更改继续并退出。我有我的保存按钮单击事件,每次保存后将所有 NUD 控件重置为 0。

我尝试了其中一种工作方式,其中我将所有 numericUpDown 控件值汇总并显示在一个文本框中,然后我将文本框放在 if 语句中,如果文本框 texchanged 然后触发消息框然后告诉用户关于未保存的更改或在文本框为空时退出。

但是,在单击保存按钮甚至清除所有控件之后,文本框的默认值为 0,因为它是从 numericUpDown 控件中获取该值的。所以当我点击退出按钮时,它告诉我我有一个 0 值的未保存更改。那不是我想要的。所以我尝试了一些不同的东西。如果我在 if 语句中只包含一个 NUD 控件,它工作正常,但是我有几个控件要包含,当我添加其余的 NUD 控件时它不会工作。就像它显示在我的代码上一样。我对 c# 还是很陌生,所以我被困住了。这是我现在拥有的代码。

private void btnExit2_Click(object sender, EventArgs e)
    {
      if (numericUpDown1RB1Rep.Value <= 0 || numericUpDown1RB2Rep.Value <= 0 || numericUpDown1RB3Rep.Value <= 0 || numericUpDown1RB4Rep.Value <= 0)


      {
        DialogResult dialogResult = MessageBox.Show("Are you sure you want to exit this application?", "Exit",
        MessageBoxButtons.YesNo, MessageBoxIcon.Question);

        if (dialogResult == DialogResult.Yes)
        {
          Application.Exit();
        }
        else if (dialogResult == DialogResult.No)
        {
          return;
        }
      }
      if (numericUpDown1RB1Rep.Value > 0 || numericUpDown1RB2Rep.Value > 0 || numericUpDown1RB3Rep.Value > 0 || numericUpDown1RB4Rep.Value > 0)
      {
        DialogResult dialog = MessageBox.Show("You have unsaved changes. Please save before closing this application", "Information",
        MessageBoxButtons.OK, MessageBoxIcon.Information);

        if (dialog == DialogResult.OK)
        {
          return;
        }

我想要一种方法或解决方案,我不必将所有 numericUpDown 控件添加到该 if 语句中,并且可能使它看起来有点优雅。或者,也许根本不必使用 if 语句。几天来,我一直在寻求帮助并尝试不同的事情。

【问题讨论】:

  • 你应该做一个控件数组。

标签: c# winforms


【解决方案1】:

如果您只想在所有 numericUpDown 为零或小于零时允许退出而不保存,那么您需要更改测试条件并使用 && 而不是 ||

if (numericUpDown1RB1Rep.Value <= 0 && 
    numericUpDown1RB2Rep.Value <= 0 && 
    numericUpDown1RB3Rep.Value <= 0 && 
    numericUpDown1RB4Rep.Value <= 0)
{
     // Exit block
}
else
{
     // Save block
}

请注意,在这种情况下您不需要单独的 if,因为如果条件为 false 显然您需要保存。

说过,正如 cmets 中所指出的,使用控件数组会让生活更轻松

public class Form1 : Form
{
    // At the form class level
    NumericUpDown[] numCtrls = new NumericUpDown[]
    {
        numericUpDown1RB1Rep, numericUpDown1RB2Rep,
        numericUpDown1RB3Rep, numericUpDown1RB4Rep
    };

    public Form1()
    {
         InitializeComponent();
    }

    ... other form's methods or events.....

}

在点击事件中

if(numCtrls.All(x => x.Value <= 0))
    // Exit block
else
    // Save block

【讨论】:

  • 这段代码可以做我想做的事。尽管当我单击退出按钮时,它不会让用户知道退出按钮由于未保存的更改而被禁用。我会想办法解决这个问题。谢谢你,非常感谢你的帮助。
  • 我尝试将 If(numCtrls.All(x => x.Value
  • 这很奇怪!您在哪一行得到了异常?
  • 我在退出按钮单击事件中遇到了该异常,这是我放置那行代码的地方。 private void btnExit2_Click(object sender, EventArgs e) { if (numCtrls.All(x => x.Value
  • 非常感谢您的帮助。我得到了它的工作。
【解决方案2】:

如果您的问题是手动添加 NumericUpDown,您可以枚举控件:

private IEnumerable<NumericUpDown> GetNumericUpDowns(Control parent)
{
    for (int i = parent.Controls.Count - 1; i <= 0; i--)
    {
        if (parent.Controls[i] is NumericUpDown)
            yield return (NumericUpDown)parent.Controls[i];
    }
}

private void btnExit2_Click(object sender, EventArgs e)
{
    var upDowns = GetNumericUpDowns(this).ToList();

    if (upDowns.Any(a => a.Value <= 0))
    {
        DialogResult dialogResult = MessageBox.Show("Are you sure you want to exit this application?", "Exit",
            MessageBoxButtons.YesNo, MessageBoxIcon.Question);

        if (dialogResult == DialogResult.Yes)
        {
            Application.Exit();
        }
        else if (dialogResult == DialogResult.No)
        {
            return;
        }
    }

    if (upDowns.Any(a => a.Value > 0))            
    {
        DialogResult dialog = MessageBox.Show(
            "You have unsaved changes. Please save before closing this application", "Information",
            MessageBoxButtons.OK, MessageBoxIcon.Information);

        if (dialog == DialogResult.OK)
        {
            return;
        }
    }
}

如果您不想检查所有 NumericUpDown 控件,您可以将标签添加到要检查的控件(例如 1)并仅检查具有此标签的控件:

private IEnumerable<NumericUpDown> GetNumericUpDowns(Control parent)
{
    for (int i = parent.Controls.Count - 1; i <= 0; i--)
    {
        if (parent.Controls[i] is NumericUpDown)
        {
            var upDown = (NumericUpDown) parent.Controls[i];

            if ((int)upDown.Tag == 1)
                yield return upDown;
        }
    }
}

【讨论】:

  • Mojtaba Tajik 我试过这段代码,但它什么也没做,消息框根本不会显示,当我点击退出按钮时,程序不会终止。
猜你喜欢
  • 1970-01-01
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 2012-11-12
  • 2022-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多