假设我在c#(winforms)中有一个简单的表单,其中包含两个文本框,一个滑块和一个名为" the_volume"的对象。每当" the_volume.value"发送一个事件(OnPropertyChanged)。在改变。如何清洁同步四个对象而不会导致无限循环?
小例子:滑块更改 - > form :: slider_changed - > the_volume已设置 - > form :: the_volume_changed - >设置滑块和texboxes值 - >无限循环...
我的第一直觉是避免在值没有变化时发送事件,但
1-我怎么知道.net控件是否会做同样的事情? (即如果值相同则不触发)
2-什么让我感到困惑的是,有一个"无用的"使用此解决方案的setter调用(set - > changed - > set - > stop loop)
答案 0 :(得分:0)
我会有一个负责路由事件的对象。我们称之为VolumeChangedEventRouter
。它将有自己的"音量变化"其他实体可以订阅的事件。
VolumeChangedEventRouter
会订阅(或订阅)您的每个控件,这些控件可能会提高"音量已更改"事件
然后,您的每个控件都会订阅(或将订阅)"卷已更改"事件为VolumeChangedEventRouter
。
然后VolumeChangedEventRouter
将知道当前的音量,因此它会知道它是否已经改变,因此是否将事件传递给其订阅者。
您可能会使用依赖注入将VolumeChangedEventRouter
传递给需要订阅其"卷已更改的每个类"事件。 (您甚至可能希望设计VolumeChangedEventRouter
,以便它实现一个仅包含"卷已更改"事件的接口,并将其传递给控件以最小化依赖关系。)
甚至可能有一个由IVolumeChanger
和所有控件实现的公共VolumeChangedEventRouter
接口,因为它们都将会提升"音量变化"事件。这会大大减少耦合。
答案 1 :(得分:0)
我知道这是一个WinForms问题,但WPF的做法应该可以帮到你。您可以研究INotifyPropertyChanged示例以获取更多详细信息,但这里是基础:
//have a backing variable
private double _volume = 0;
//have a property
public double Volume
{
get { return _volume; }
set
{
// prevent any event firing if nothing changed
if( _volume == value )
{
return;
}
// now we can set
_volume = value;
// something really changed, fire some event
this.NotifyPropertyChanged();
}
}
现在所有听众只会在确实发生变化时收到通知。然后这种类型的检查可以应用于几乎任何观察者模式问题。这将阻止您在问题中声明的事件循环。