编写GUI时,我经常遇到以下问题:假设您有一个模型和一个控制器。控制器有一个小部件W
,用于显示模型的属性X
。在GUI中突破事件周期
由于模型可能会从控制器外部更改(可能有其他控制器使用相同的模型,撤消操作等),因此控制器会侦听模型上的更改。控制器还监听小部件W
上的事件并相应地更新属性X
。
现在,将出现以下情况:
- 产生一个事件在
W
的值改变,在控制器在调用处理程序 - 的控制器设置新值对于
X
中的型号 - m Odel等发射事件,因为它已经被改变
- 的控制器接收来自模型的变化事件
- 的控制器得到的
X
值,并将其设置在微件 - 转到1.
有几种可能的解决方案为:
- 修改控制器以在模型更新时设置标志,并且如果设置此标志,则不响应来自模型的任何事件。
- 断开控制器暂时(或告诉模式不发送一段时间的任何事件)
- 从窗口小部件
在过去的冻结任何更新,我经常去的选项1,因为它是最简单的事情。它有用标志混乱你的类的缺点,但其他方法也有它们的缺点。为了记录,我已经遇到了包括GTK +,Qt和SWT在内的几个GUI工具包的问题,所以我认为它非常适用于工具包不可知论的问题。
任何最佳实践?或者我使用的架构完全错误?
@Shy:这是某些情况下的解决方案,但如果从控制器外部更改X
(例如,使用命令模式进行撤销/重做时),仍会发生一轮多余的事件,已更改,W
已更新并触发了一个事件。为了防止对模型进行另一次(无用的)更新,必须吞噬由Widget生成的事件。
在其他情况下,模型可能更加复杂,并且简单地检查确切的改变可能是不可行的,例如,一个复杂的树视图。
我在MFC中一直有列表框出现此问题。 – 2008-09-24 00:34:58