【问题标题】:MFC slider+edit+spinner patternMFC滑块+编辑+微调器模式
【发布时间】:2017-10-28 01:00:58
【问题描述】:

在我控制外部设备的基于对话框的 UI 中,我有一堆外观和行为相似的“旋钮”:由 滑块数字编辑框组成的三组控件,以及用于该数字编辑框的 微调器

值的变化会导致到该外部设备的往返,因此我自然会尝试每次“更改”只调用一次冗长的 API。更改可以来自 3 个控件中的任何一个,并且它们必须是同步的,显然。这在实践中意味着如果编辑框发生变化 - 它需要更改滑块的位置。反之亦然。

API 调用在单独的函数中实现,只要 UI 框架报告值发生变化,就会调用这些函数。

问题:

  1. 当控件开始相互更新时,“同步”范例的直接天真实现自然会导致递归调用
  2. 引入递归保护(如bool m_processingUserInput;)看起来很丑,坦率地说,感觉很丑
  3. 当添加更多控件时,“仅”从一种类型的控件而不是另一种(例如仅从滑块)进行 API 调用很容易出现错误。此外,这种方法使代码看起来很混乱,并且(就其本身而言)也不能解决递归问题

我的问题是:我是否错过了人们用来编写此 UI 交互代码的成熟模式?请告诉我一种优雅高效的方法。

【问题讨论】:

  • 不会出现递归,因为您提到的所有控件都不会在以编程方式更改时发送“已更改”通知。通知是关于用户修改的。
  • SetDlgItemInt(ID, val) 肯定会触发“on change”处理程序
  • 好吧,我错了。这来自从字面上阅读 MS 文档,而不是自己测试。递归保护听起来并不那么糟糕。您可以使用通知处理程序内部的布尔静态变量和 RAII 类的局部变量来做到这一点,该变量在构造函数中将静态变量设置为true,在析构函数中设置为false,以实现异常安全和易用性。

标签: c++ windows user-interface mfc


【解决方案1】:

第一个更改的控件应触发“值更新”事件。其他控件应订阅该事件并在其 OnUpdate 方法中重新绘制可视元素。您可以在 Windows API 之上构建它,或者使用 MFC 的内置文档视图架构,这基本上是他们对模型-视图-控制器模式的实现:

https://www.codeproject.com/Articles/30291/An-Introduction-to-a-Model-View-Controller-Impleme

【讨论】:

  • 这看起来会有很多子类化来支持该模型。还是我误解了“订阅事件”的方法?
  • 您可以根据应用程序的复杂性来决定模型是否合理。如果您正在寻找一个快速而肮脏的解决方案,您总是可以使需要更新的控件无效,并让它们用新值重新绘制自己。
  • 使用新值重新绘制,必须首先设置新值,这可以追溯到我描述的递归问题:(
  • ??该值在第一个控件中设置。没有递归。您将拥有自己的控制器,该控制器将保存所有三个(或您拥有的多个)控件的值。这是不涉及使用框架的快速解决方案。
猜你喜欢
  • 1970-01-01
  • 2021-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多