我有一个关于在.Net中更新控件的问题,这样如果用户更新一个字段,另一个字段将自动更新一些数据,反之亦然。我正在使用两个NumericUpDown控件来转换一些数据。
我遇到的问题是,我正在使用ValueChanged事件。因此,有时这些控件会卡在一个循环中,其中一个控件更新另一个控件而另一个控件更新第一个控件。结果有点随机。
那么,处理这种情况的最佳方法是什么?简而言之,我只想更新另一个控件,如果第一个控件是由用户自己修改的。
非常感谢任何帮助。
答案 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;
}