2009-12-18 36 views
0

Im在设计问题上挣扎了一下。我在c#中制作了一个非常简单的gui系统。该代码旨在可重用,所以我在这里寻找最灵活的解决方案。我提出的解决方案似乎都有其缺点。设计事件驱动通信的问题

为了简单起见,假设有三个类:控制器,按钮和客户端代码。客户端代码是使用gui系统的代码。它创建控制器并在其上调用Update()。控制器创建一堆按钮实例并在其上调用Update()。按钮绘制自己并检查鼠标点击。

现在的问题是如何得到一个按钮被点击的客户端代码的事实?

选项1:将GetButton(字符串名称)添加到控制器类。客户端代码然后可以订阅按钮类中定义的事件=> GetButton(“but”)。MouseUpEvent + = MouseUpHandler;这样做的缺点是这暴露了Button.Update(),它应该只能被控制器使用。

选项2:有控制器订阅所有按钮和客户端代码订阅控制器。这里的缺点是更多的解析客户端代码中的代码,因为现在所有的事件都通过控制器进行传输,所以客户端必须检查哪个按钮发送了每个事件。我喜欢在初始化阶段设置事件流,如选项1中所示。

选项3:为每个事件添加订阅/取消订阅方法到控制器(SubscribeMouseUp(string buttonName,GUIDelegate del)等)。缺点是控制器API快速增长。

所以现在我倾向于选择1,但GetButton返回一个接口(IClientButton也许),它只声明事件,从而隐藏客户端的Update(),但林不知道这是如何接口应该是用过的。

任何洞察力是赞赏。 巴斯

回答

0

想必这是一个问题,因为Update()是公开的?

假设你已经安排你的按钮和控制器到同一个命名空间将使用internal保护满足您的需求?

0

接口可用于这种方式,INotifyPropertyChanged的是具有1个项目是一个事件的interace。

有关使用RoutedEvents什么?

0

还有第四种,也许更受欢迎的选项。

有一个调度器作为注册/注销的中心位置。所有事件接收方都会向调度员注册回调。所有事件生成器都将其事件发送给调度员。

它保持API清洁,并有助于解开对象引用。

0

在您的控制器中,添加两个事件 - ButtonCreatedButtonDestroyed

public event EventHandler<ClientButtonEventArgs> ButtonCreated; 
public event EventHandler<ClientButtonEventArgs> ButtonDestroyed; 

ClientButtonEventArgs仅仅是在你IClientButton接口的EventArgs包装。

让您的客户端代码订阅这两个事件。当控制器创建一个新按钮时,让它触发ButtonCreated事件。客户端代码可以在收到事件通知时订阅必要的Button事件。同样,控制器将根据需要触发ButtonDestroyed事件,允许客户端代码取消订阅Button的事件。

以这种方式,整个序列是事件驱动的。客户端代码反应创建和销毁一个按钮,它看起来像是你在做什么。