在视图模型中具有WPF特定内容的优缺点

7

我对这段代码的想法有些犹豫:

public SolidColorBrush Brush
{
    get { return IsValid ? _validItemBrush : _invalidItemBrush; }
}

这是我目前项目中视图模型的一部分,可以想象,Brush将绑定到UI中的一些文本元素,以指示其他数据片段的(无)效性,在一个相当简单和直截了当的对话框中。
支持这段代码的人认为,既然我们正在使用WPF,那么我们可以在视图模型中允许一些简单的WPF特定结构。
反对者认为,这违反了“关注点分离”原则,因为它明确地定义了应该由视图独自处理的样式问题。
请分享您的观点,如果您对上面的代码不满意,请分享您有关替代解决方案的想法。(我特别想知道您对使用DataTemplate的看法。)
是否存在可以被视为最佳实践的解决方案?

这与“DataTemplate”有什么关系? - Reed Copsey
@Reed Copsey:我的印象是,使用映射到特定“DataType”的“DataTemplate”是解决问题的另一种替代方案。我想知道它是否被使用或者是否被认为过于“笨重”。 - Christoffer Lette
使用DataTemplate并不是处理画刷更改的适当方式。它们真正的作用是确定如何显示自定义类型。例如,它们可以用于将自定义类映射到设计为适当显示该类信息的视图。 - Reed Copsey
3个回答

8
个人而言,我会在XAML中定义这两个画笔,并让使用它们的控件根据IsValid属性(在XAML中)切换画笔。这可以非常容易地通过DataTriggers或甚至一个单一的IValueConverter来实现——转换器可以接受2个画笔和一个布尔值,并在它们之间轻松切换。
这样保持业务逻辑与表现层分离——“画笔”是非常特定于特定形式的表现方式,是纯粹的视图选择。将其硬编码到ViewModel中既违反了单一职责原则,也不是干净的关注点分离。
我非常希望将其保留在View中,并根据ViewModel特定的IsValid(绑定)属性进行切换。

1
说得好。如果你在考虑“最佳实践”这个短语时想到了在哪里定义画笔,答案是DataTrigger/IValueConverter,而不是ViewModel。 - Dan J

2
虽然有些情况下我可能会在视图模型中使用WPF结构,但这并不是其中之一。原因如下:
- 更难更改。如果你将brushes定义为资源并在样式中使用它们,那么更改应用程序的颜色方案只需要加载不同的资源字典即可。如果你在视图模型中硬编码颜色值,那么如果最终用户需要不同的颜色,你就需要改变很多不同的东西。 - 更难测试。如果你想编写一个单元测试来检查属性是否返回正确的brush,你必须在单元测试中创建一个brush并比较两个值,因为它是一个引用类型。 - 在许多甚至大多数情况下,它并没有使代码更简单或更易于维护。你很可能已经在使用样式(假设你熟悉样式),因为它们让WPF中的几乎所有内容都变得更加容易。将IsValid绑定到brush颜色只需要在样式中添加DataTrigger即可。任何维护此代码的人都会在那里找到它。
当然,有时候我确实会在视图模型中使用WPF结构 - 例如,很久以前就已经停止纠结于视图模型是否公开了Visibility类型的属性。请注意,上述问题都不适用于该情况。

0
在像你这样纯粹是美观方面的情况下,我使用触发器或可视状态管理器来更改颜色。
有时我会在我的ViewModels中使用颜色,但只有当它是我的软件规范的一部分时才会这样做(例如,显示患者CO2的图表的颜色取决于本地化)。在这种情况下,我使用一个Color结构绑定属性,允许View使用Color进行SolidColorBrush、GradientStop或任何它想要的操作。我最初使用了#AARRGGBB格式的字符串来完全消除WPF依赖,但我的经验丰富的同事不喜欢那样做。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接