处理控件自动更新的最佳方式

本文关键字:最佳 方式 更新 控件 处理 | 更新日期: 2023-09-27 18:15:51

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

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

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

处理控件自动更新的最佳方式

只需在类中使用布尔保护来检查您是否在更新方法中。当您正在更新时,将来从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;
    }        
}

我建议您使用数据绑定并绑定到作为模型的对象。然后,您的模型是根据属性的更改更改其他值的逻辑所在。模型还会引发IPropertyChanged/IPropertyChanging事件,UI会接收到这些事件。这不仅可以防止你所描述的问题,它还可以保持业务逻辑在你的UI层之外,如果你转移到其他东西(比如从WinForms到WPF,或Asp. js)。净MVC)。

如果方法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;
}

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

我喜欢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;
}