【发布时间】:2008-09-24 00:25:42
【问题描述】:
在编写 GUI 时,我经常遇到以下问题:假设您有一个模型和一个控制器。控制器有一个小部件W,用于显示模型的属性X。
因为模型可能会从控制器外部更改(可能有其他控制器使用相同的模型、撤消操作等),因此控制器会监听模型的更改。控制器还会监听小部件W 上的事件并相应地更新属性X。
现在,发生了以下情况:
-
W中的值已更改 - 产生一个事件,调用控制器中的处理程序
-
控制器在模型中为
X设置新值 - 模型发出事件,因为它已被更改
- 控制器收到来自模型的更改事件
-
控制器获取
X的值并将其设置在小部件中 - 转到 1。
有几种可能的解决方案:
- 修改控制器以在模型更新时设置一个标志,如果设置了此标志,则不对来自模型的任何事件作出反应。
- 暂时断开控制器(或告诉模型一段时间不要发送任何事件)
- 冻结小部件的所有更新
过去,我通常选择选项 1,因为这是最简单的事情。它的缺点是会使你的类被标志弄得杂乱无章,但其他方法也有它们的缺点。
为了记录,我在几个 GUI 工具包中遇到过这个问题,包括 GTK+、Qt 和 SWT,所以我认为它与工具包无关。
有什么最佳实践吗?还是我使用的架构完全错误?
@Shy:这在某些情况下是一种解决方案,但是如果从控制器外部更改X(例如,使用撤消/重做的命令模式时),您仍然会得到一轮多余的事件,因为那时值已更改,W 已更新并触发事件。为了防止对模型进行另一次(无用的)更新,必须吞下小部件生成的事件。
在其他情况下,模型可能更复杂,简单检查究竟发生了什么变化可能不可行,例如一个复杂的树视图。
【问题讨论】:
-
我在 MFC 中的列表框一直有这个问题。
标签: user-interface events