Как мне запретить пользователю выходить из программы, если в форме есть несохраненные изменения? - PullRequest
0 голосов
/ 09 мая 2019

У меня есть Winforms с несколькими элементами управления numericUpDown, и я хочу, чтобы программа предупреждала пользователя, когда он нажимает кнопку выхода в форме, если у него есть несохраненные изменения и если нет несохраненных изменений, чтобы продолжить и выйти. У меня есть событие нажатия кнопки сохранения, чтобы сбросить все элементы управления NUD на 0 после каждого сохранения.

Я попробовал несколько способов, как один из них работал, где у меня были все значения элемента управления numericUpDown, суммируемые и отображаемые внутри текстового поля, а затем я помещал текстовое поле в оператор if и вызывал окно сообщения, если текстовое поле поменялось, затем сказал пользователю о несохраненных изменениях или о выходе, если текстовое поле имеет нулевое значение.

Однако после нажатия кнопки сохранения даже удаляются все элементы управления, значение текстового поля по умолчанию равно 0, поскольку оно получает это значение из элементов управления numericUpDown. Поэтому, когда я нажимаю кнопку выхода, это говорит мне, что у меня есть несохраненные изменения со значением 0. Это не то, что я хочу. Поэтому я попробовал что-то другое. И это работает нормально, если я включаю только один элемент управления NUD внутри оператора if, но у меня есть несколько элементов управления, и он не будет работать, когда я добавлю остальные элементы управления 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. Я пытаюсь найти помощь и пробую разные вещи в течение нескольких дней.

Ответы [ 2 ]

0 голосов
/ 09 мая 2019

Если ваша проблема заключается в добавлении 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;
        }
    }
}
0 голосов
/ 09 мая 2019

Если вы хотите разрешить выход без сохранения, только когда все ваши numericUpDown равны нулю или меньше, вам нужно изменить условие теста и использовать && вместо ||

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

Обратите внимание, что в этом случае вам не нужно отдельное выражение, потому что если условие ложное, очевидно, вам нужно сохранить.

Сказал, что, как указано в комментариях, использование массива ваших элементов управления облегчит жизнь

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...