无限循环的事件

时间:2016-05-17 13:16:46

标签: c# winforms events delegates observer-pattern

假设我在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)

2 个答案:

答案 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();
    }
}

现在所有听众只会在确实发生变化时收到通知。然后这种类型的检查可以应用于几乎任何观察者模式问题。这将阻止您在问题中声明的事件循环。