处理控件自动更新的最佳方式
本文关键字:最佳 方式 更新 控件 处理 | 更新日期: 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;
}