Как сделать так, чтобы пользователь передумал без логических флагов? - PullRequest
2 голосов
/ 19 августа 2011

У меня есть NumericUpDown в моем приложении, но это опасно.При изменении значения весь документ стирается.Из-за этого я хотел бы предупредить пользователя (даже если он случайно нажмет OK, он может отменить его).

Проблема в том, что, похоже, единственное событие, которое я мог обработать, это ValueChangedсобытие, и я бы в конечном итоге с кодом, как этот.

private bool ignoreValueChanged = false;

private void numFoobar_ValueChanged(object sender, EventArgs e)
{
    if (ignoreValueChanged)
    {
        ignoreValueChanged = false;
        return;
    }

    if (MessageBox.Show("This will erase the entire document. Are you sure?", "Confirmation", MessageBoxButtons.OKCancel) == DialogResult.Cancel)
    {
        ignoreValueChanged = true;
        numFoobar.Value = oldValue; // The ValueChanged event gets called again =/
        return;
    }

    // More code
}

Должен быть лучший способ.Я надеялся, что Validating поможет, но он вызывается только при закрытии формы, которая кажется.

Ответы [ 4 ]

0 голосов
/ 19 августа 2011

Погуглил немного. Сначала я придумал это:

typeof(NumericUpDown).GetField("currentValue", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(numericUpDown1, 5m);

Что работает, но это отражение, и, кажется, это немного излишне, поэтому я решил против этого. Тогда я нашел это:

C # winforms числовое управление вниз

И основал мое решение на втором ответе, который не так уж и плох, если честно.

0 голосов
/ 19 августа 2011

Сделал некоторое гугление, и вот что может сработать:

private void numFoobar_ValueChanged(object sender, EventArgs e)
{

    this.ValidateChildren();
}

private void numFoobar_Validating(object sender, CancelEventArgs e)
{

    if (MessageBox.Show("This will erase the entire document. Are you sure?", "Confirmation", MessageBoxButtons.OKCancel) == DialogResult.Cancel)
    {
        e.Cancel = true;
    }
}

Обратите внимание, что вам нужно сбросить значение, так как отмена проверки не меняет значение.Но это единственный способ, которым я смог запустить событие Validating.

Метод ContainerControl.ValidateChildren

Есть несколько проблем, с которыми нужно разобраться,однако:

  1. При выходе из программы она снова запускает событие Validating;вероятно, нужно обработать его в одном из событий закрытия для формы или приложения.

  2. Я играл со сбросом значения в событии ValueChanged, но это снова вызвало событие Validating.

Я еще немного поиграюсь с этим и посмотрю, смогу ли я найти более надежное решение для вас.

0 голосов
/ 19 августа 2011

Это действительно проблема юзабилити.Я предполагаю, что вы пытаетесь игнорировать событие valueChanged, когда значение меняется на текущее постоянное значение.Один из вариантов - сравнить с текущим значением, на котором основан документ.

0 голосов
/ 19 августа 2011

О, хорошо, вы можете удалить событие, подписанное на элемент управления numericUpdown, перед сбросом его значения, после сброса, а затем снова подписать его обратно.Таким образом, событие не вызывается при сбросе значения.

Но я также думаю о том, как проверить, подписано ли событие уже или нет.Но вышеупомянутый метод даст вам половину решения.

Здесь я немного попробовал это, и это, кажется, работает, но я не могу понять, как проверить, подписано ли уже то же самое событие или нет.

void NumericUpDown1ValueChanged(object sender, EventArgs e)
        {
            if(numericUpDown1.Value > 10)
            {numericUpDown1.ValueChanged -= new System.EventHandler(this.NumericUpDown1ValueChanged);
            numericUpDown1.Text = "5";
            }               
            else numericUpDown1.ValueChanged += NumericUpDown1ValueChanged;//Here i need to first check if already it is subscribed or not before such that i dont want to subscribe double time
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...