处理控件的最佳方法是自动更新对方?

时间:2013-05-29 18:28:47

标签: c# .net

我有一个关于在.Net中更新控件的问题,这样如果用户更新一个字段,另一个字段将自动更新一些数据,反之亦然。我正在使用两个NumericUpDown控件来转换一些数据。

我遇到的问题是,我正在使用ValueChanged事件。因此,有时这些控件会卡在一个循环中,其中一个控件更新另一个控件而另一个控件更新第一个控件。结果有点随机。

那么,处理这种情况的最佳方法是什么?简而言之,我只想更新另一个控件,如果第一个控件是由用户自己修改的。

非常感谢任何帮助。

4 个答案:

答案 0 :(得分:2)

如果方法Foo处理一个控件的事件而方法Bar处理另一个控件的事件,那么Foo应该更改Bar控件的值反之亦然。但是你应该在某个地方使用一个控制变量(比如,对触发事件的控件的引用是一个好主意)。因此,如果调用Foo

  • Foo更新Bar控件的值;
  • Bar的控件会触发其事件,并调用Bar;
  • Bar检查首先拍摄的控件的参考,发现它不是它的控制,并且什么都不做。

同样的逻辑适用于Bar

这样你就不会得到无限循环。

在代码中,它看起来像这样:

nud1.ValueChanged += new Eventhandler(Foo);
nud2.ValueChanged += new Eventhandler(Bar);
NumericUpDown shooter = null;

private void Foo (object sender, EventArgs e)
{
    if (this.shooter == null)
    {
        this.shooter = nud1;
        nud2.Value = nud1.Value;
    }
    else this.shooter = null;
}

private void Bar (object sender, EventArgs e)
{
    if (this.shooter == null)
    {
        this.shooter = nud2;
        nud1.Value = nud2.Value;
    }
    else this.shooter = null;
}

当然,这是一个粗略的例子(例如,它假设两个控件的值总是在变化。适应你的情况。

答案 1 :(得分:2)

只需在类中使用布尔保护来检查您是否在更新方法中。 在您进行更新时,将忽略从NUD触发的所有未来事件。

private boolean updating = false; // Class level variable

void event_handler(...) // The function hooked up to the ValueChanged event
{
    if( !updating )
    {
        updating = true;
        // Do your calculations and update the NUDs
        updating = false;
    }        
}

答案 2 :(得分:2)

我建议您使用数据绑定并绑定到作为模型的对象。然后,您的模型就是根据属性的变化改变其他值的逻辑。该模型还引发了UI将接收的IPropertyChanged / IPropertyChanging事件。这不仅会阻止您描述的问题,而且如果您转移到其他地方(例如从WinForms到WPF或Asp.Net MVC),它还会将此业务逻辑保留在UI层之外。

答案 3 :(得分:1)

我喜欢Andy关于使用MVC模式的回应,但是如果对于这种特定情况这种变化过于激进,则只有在当前值与分配的值不同时才应设置值。这样可以防止ValueChanged事件再次触发,并在第一次递归时停止无限循环。

// Inside your value changed handler for Control2,
// instead of directly setting the value of Control1, do this:
if(Control1.Value != valueBeingSet)
{
    Control1.Value = valueBeingSet;
}