UI状态的处理

Posted

技术标签:

【中文标题】UI状态的处理【英文标题】:Handling of UI state 【发布时间】:2009-03-01 15:43:09 【问题描述】:

我有使用 MFC 编写的在 Windows 上运行的应用程序。菜单项的启用/禁用状态取决于很多条件。例如,如果满足条件 A 或满足条件 B,我必须启用菜单项,但如果 A 和 B 同时为真,则应禁用该菜单项。我们如何在代码中对此进行建模?我想我应该使用某种状态机,但我的状态机似乎包含太多状态。处理此类问题的一般方法是什么?请注意,以上只是一个例子,这样的条件还有很多。此外,始终启用菜单并在用户按下它时显示错误消息的选项不存在,因为我必须禁用菜单。

澄清一下,我不是在寻找如何禁用 MFC 中的菜单项,而是在寻找在有许多相互依赖的状态时决定是否启用/禁用菜单项的最佳方法是参与。

【问题讨论】:

【参考方案1】:

MFC 具有用于启用和禁用菜单项的内置机制,以命令路由和ON_UPDATE_COMMAND_UI 宏的形式。有关详细信息,请参阅 MSDN 中的 How to: Update User-Interface Objects 和 CCmdUI 类文档。

您不一定需要状态机。对于每个菜单命令,决定应该在哪里处理命令,例如,在您的文档、视图或主框架类中,然后实现一个 OnUpdate 处理程序并为相应的类添加一个 ON_UPDATE_COMMAND_UI 消息映射条目。

例如,看看我给this question的答案。

【讨论】:

ON_UPDATE_COMMAND_UI 仅用于相对简单的菜单和工具栏。主要问题是如何启用/禁用 ON_UPDATE_COMMAND_UI 无法处理的对话框上的控件。【参考方案2】:

尝试编写一个方法,updateUIStatus(),在每个 UI 操作后调用它。该方法将根据您的条件设置菜单项(以及任何其他 UI 组件)的启用或禁用状态。

使用单一方法进行所有 UI 状态更新的好处是您可以将所有这些逻辑集中在一个地方,而不是多次调用 if (condition A && condition B) menu.setEnabled(true);

【讨论】:

然而,不利的一面是拥有庞大的业务逻辑方法的风险:( 我知道,我也想过。但由于它是在 UI 端,它并不是真正的业务逻辑。如果其中有业务逻辑决策,则应调用其他类(即,在某些业务逻辑类中调用“isOptionValid()”) 是的。无论哪种方式,最好将这段代码放在一个地方,而不是分散在整个应用程序中(对于这个特定场景) 我在自己的一个项目中采用了这种方式,但并不喜欢它。在每个 GUI 操作之后调用这个函数非常令人困惑,并且某些 gui 操作不必调用它。总的来说,即使对我来说,遵循逻辑也非常令人困惑。我认为 state 方法最终会添加许多类,但也许仍然是更好的方法。【参考方案3】:

看看mediator pattern。它旨在跟踪此类内容。

来自 gof:

在以下情况下使用中介者模式

一组对象以定义明确但复杂的方式进行通信。由此产生的相互依赖是非结构化的,难以理解。

重用一个对象很困难,因为它引用了许多其他对象并与之通信。

分布在多个类之间的行为应该是可定制的,无需大量子类化。

【讨论】:

以上是关于UI状态的处理的主要内容,如果未能解决你的问题,请参考以下文章

使用 Flux 和 React 处理 UI 状态

使用 Angular UI-Router 在 Ionic 框架中将状态作为新路由处理

状态栏高度变化处理

iOS MVVM 处理初始视图状态

使用后台线程BackgroundWorker处理任务的总结

从材料 ui 处理自动完成组件的更改