ViewModel中的WPF相关属性是否违反了MVVM最佳实践?

Tho*_*enz 9 wpf mvvm separation-of-concerns

这是一个详细说明的示例:

我在我的视图中使用ItemsControl动态创建一个简单的条形图,并将项目绑定到我的BarGraphViewModel中的BarViewModel集合(每个包含一个值的百分比).每个酒吧应该有不同的颜色.颜色应该从一个集合中选择,例如{Color1, Color2, ..}

集合本身是不变的,但条数将取决于具体情况.

一个简单的解决方案是创建一个简单的BarViewModel,如下所示:

public class BarViewModel
{
    public int Percentage { get; set; }

    public SolidColorBrush Stroke { get; private set; }

    public BarGraphViewModel(SolidColorBrush stroke)
    {
        Stroke = stroke;
    }
}
Run Code Online (Sandbox Code Playgroud)

(为了简洁,我省略了属性更改和验证实现)

现在我可以从我的BarGraphViewModel为每个百分比创建一个BarViewModel,并传入从我的Color集合创建的相应ColorBrush.

然后在Xaml中我将创建一个简单的ItemsTemplate,它将绑定到这些属性.

只有现在,因为它包含一个SolidColorBrush类型的属性,我的ViewModel依赖于Presentation框架,如果我想在另一个环境中使用它,它将不得不被更改.

这是否会打破MVVM最佳实践,或者它是否可以接受(你必须在某处绘制线条或者事情变得太复杂)

我只是想看看其他人对此的看法,以及是否有其他解决方案让ViewModel完全不了解Presentation Layer而不会太复杂.我可以想象ValueConverters可以提供帮助吗?

Pan*_*nek 8

从理论上讲,您所描述的情况与MVVM中的最佳实践相悖.但是有一个简单的解决方案可以清理您的视图模型.您应该创建自己的类型来表示视图模型中的颜色 - 它可以是string,int或enum.然后,您可以编写自定义ValueConverter(实现IValueConverter)以将视图模型颜色类型转换为依赖于表示框架的颜色表示.转换器应与边界表达式一起使用.转换绑定值的示例在此处.


Hap*_*mad 8

在Martin Fowler描述的原始Presentation Model模式中,视图"询问"视图模型如何显示自身.这似乎有利于在视图模型上放置颜色和大小属性,而不是在视图中使用触发器.然而,在WPF中应用这种模式有些不同.在WPF中,你通常会定义如何的观点看起来通过在视图中使用样式和的DataTemplates.直接从视图模型返回特定颜色将与此方法相反.所以简短的回答是:不,不要在视图模型上添加颜色属性.

同样在原始的Presentation Model模式中,视图模型是视图的抽象.因此,不是返回确切的颜色,最好返回一个"键",然后视图可以用来查找实际颜色.例如,代替PersonViewModel.FaceColor返回Red,你将有PersonViewModel.Mood返回Angry.然后,视图可以使用Style或DataTemplate触发器将其转换为实际的红色.

所以这是我的答案,我坚持不懈,但从另一个方向考虑争论也很有趣.其一,把颜色属性上的视图模型仍然是单位可测试的,这似乎已成为什么视图模型还好的主要性判据.

对视图技术保持"不可知"并不是两个方向的重要因素.保持视图模型与其他视图技术的二进制兼容性的目标仅在XAML系列中是现实的.将所有视图模型移动到他们自己的项目,这个项目缺乏对WPF的直接依赖是个不错的主意.但是您必须排除使用ICommand的任何内容,或者对WindowsBase.dll引用进行例外处理.但实际上,它不会给你带来太大的收益.我们非常关注Micrsoft技术!如果您决定移植到另一个GUI框架,那么我的猜测是您正在查看源代码转换.我等着看微软是否在我尝试之前就已经解决了;)移植可能包括改变你的颜色类型,如果你决定把它们放在你的视图模型中.虽然不是视图模型上对颜色属性的原因,但它也不是理由.