【发布时间】:2011-10-15 22:25:19
【问题描述】:
我使用 MVVM(或我自己的风格)已经有一段时间了,但我仍然想澄清它的一个方面。
(免责声明:我之前看到过一些类似的问题,但我还没有看到任何考虑到专门为视图更改数据类型的优点/缺点。如果我错过了一些重要的事情,但每第三个网页似乎在某处有“MVVM”=p)
问题: 用户需要选择活动的持续时间。他们可以选择默认活动长度的倍数(也称为 BlockSize),或者对于那些“特殊场合”,我们允许他们否决这一点并从 5 分钟间隔中进行选择。
对于 UI,我们决定为此使用组合框和切换按钮。默认情况下,ComboBox将显示{“1块”,“2块”,“3块”},或者在选中“自定义持续时间”ToggleButton时:{“5分钟”,“10分钟”,“15分钟” }
3 种可能的解决方案:
理想情况下(为了可扩展性),ViewModel 会公开一个ObservableCollection<TimeSpan> 以将它的 Combobox 绑定到。但在这种情况下,我应该如何为“Block/s”或“Minute/s”添加后缀。单次使用的多值转换器可以工作,但这会产生大量样板代码,而且我不喜欢你必须实施多少类型检查,因为它们不是强类型的。
另一种方法是使用 ViewModel 公开ObservableCollection<string>,但在这种情况下,我必须编写一个方法来转换"3 Blocks" => new TimeSpan( 0, 3 * BlockSize, 0 ),这听起来比 MultiConverter 更有吸引力。在这种情况下,它是一个相当简单的 1-1 映射,但即便如此,我还是很想创建 4 个属性和一个方法来控制它。这似乎是为单个绑定管理的代码分配。
private Dictionary<string, TimeSpan> selectedDurationMap { get; set; }
private ObservableCollection<string> availableCustomDurations { get; set; }
private ObservableCollection<string> availableBlockDurations { get; set; }
public ObservableCollection<string> AvailableDurations { get; private set; }
private fillDurationLists( TimeSpan maximumDuration, TimeSpan blockDuration ) { }
另一个是有多个组合框,它们的显示/隐藏取决于是否选择了“自定义持续时间”切换按钮。两者都可以使用内置的 StringFormat 来附加“块”或“分钟”,而我可以将可用持续时间保持为 TimeSpan 格式。到目前为止,这是我倾向于支持的那种解决方案,但是虽然简单的实现符合所有要求,但它的可扩展性不是很好
例如,要添加对复数形式(块与块)的控制,我需要一个 ValueConverter,在这种情况下,解决方案 1 更具可扩展性、可读性和效率(一半的视觉元素),同时以更少的代码实现相同的目标(好的,所以这是一个玩具问题,但这是我遇到的一个相当典型的场景)
【问题讨论】:
-
阅读时间很长,可以改写吗?
-
似乎 VM 应该公开
Count和CountUnit属性,并且 UI 应该处理如何格式化它以进行显示。
标签: wpf data-binding mvvm viewmodel