如何在没有布尔标志的情况下处理用户改变主意?

时间:2011-08-19 05:46:57

标签: c# winforms

我的应用程序中有一个NumericUpDown但它很危险。更改值后,将删除整个文档。因此,我想给用户一个警告(即使他不小心碰到了他可以撤消它。)

问题是我似乎唯一可以处理的事件是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
}

必须有更好的方法。我希望验证会有所帮助,但只有在关闭表格时才会调用它。

4 个答案:

答案 0 :(得分:0)

哦,您可以在重置其值之前删除订阅了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
        }

答案 1 :(得分:0)

做了一些谷歌搜索,这里有可能有用的东西:

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

请注意,您需要重置该值,因为取消验证不会更改该值。但这是我能够启动验证事件的唯一方法。

ContainerControl.ValidateChildren Method

然而,有几个问题需要解决:

  1. 退出程序时,会再次触发Validating事件;可能需要在表单或应用程序的一个结束事件中处理它。

  2. 我玩过重置ValueChanged事件中的值,但是再次触发了Validating事件。

  3. 我会继续玩它一点,看看我是否能为你提出更实用的解决方案。

答案 2 :(得分:0)

这实际上是一个可用性问题。我想你要做的是在值变为当前持久值时忽略valueChanged事件。一种选择是与文档所基于的当前值进行比较。

答案 3 :(得分:0)

谷歌搜索了一下。首先,我想出了这个:

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

哪个有效,但它是反射,它似乎有点超过顶部所以我决定反对它。然后我发现了这个:

C# winforms numericupdown control

基于第二个答案我的解决方案,说实话并不是那么糟糕。