开发者

How to handle the user changing his mind without boolean flags?

I have a NumericUpDown in my application but it is dangerous. When the value is changed the entire document is erased. Because of this, I'd like to give the user a warning (even if he accidentally hits OK he can undo it.)

The problem is that it seem开发者_开发问答s that the only event I could handle would be the ValueChanged event and I'd end up with code like this.

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
}

There has got to be a better way. I was hoping Validating would help but it is only called when closing the form it seems.


Oh well you could remove the event subscribed to the numericUpdown control before resetting its value, after resetting it then again subscribe it back. This way, the event is not called when you reset the value.

But i am also thinking about how to check if the event is already subscribed or not. But above said method shall give you half the solution.

Here i tried this a bit and it seems to work but i cant seem to figure out how to check if already that same event is subscribed or not.

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
        }


Did some Googling, and here's something that might work:

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;
    }
}

Note that you'll need to reset the value as canceling the validation doesn't change the value. But this is the only way I was able to get the Validating event to fire.

ContainerControl.ValidateChildren Method

There are couple of issues to work out with this, however:

  1. When exiting the program, it will fire the Validating event again; probably need to handle it in one of the closing events for the form or application.

  2. I played with resetting the value in the ValueChanged event, but that trigged the Validating event again.

I'll keep playing with it for a bit and see if I can come up with a more solid solution for you.


This is really a usability issue. I guess what you are trying to do is to ignore the valueChanged event when the value has changed to the current persistent value. One option is to compare with the current value the document is based on.


Been googling a bit. First, I came up with this:

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

Which works but it is reflection and it seems a little over the top so I decided against it. Then I found this:

C# winforms numericupdown control

And based my solution on the second answer, which isn't so bad to be honest.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜