如何在MVVM模式中使用WPF转换器?

时间:2009-06-17 14:42:54

标签: wpf mvvm

假设我有一个绑定到 ViewModel A 的视图,该视图具有可观察的集合客户

这个MVVM模式的一个优点是我还可以将View绑定到 ViewModel B ,并用不同的数据填充它。

但如果在我的查看转换器转换器中显示我的客户,例如我有一个“ContractToCustomerConverter”接受合同并返回要显示的相应客户。

问题在于转换器存在于MVVM模式之外,因此不知道我的ViewModel还有其他客户来源。

  • 是否有办法让 View将ViewModel传递给Converter ,以便它参与MVVM模式提供的解耦?
  • 有没有办法让我以某种方式在我的ViewModel中包含Converter ,以便转换器使用ViewModel可用的当前依赖项?
  • 或转换器只是美化代码隐藏,因此没有在MVVM模式中使用,因此如果您使用的是MVVM,那么您只需创建自己的“转换器”(ViewModel类上的方法)返回要在视图上使用的图像对象,可见性对象,FlowDocuments等,而不是使用转换器?

(在MVVM Template Toolkit download附带的WPF演示应用程序中看到转换器的使用后,我遇到了这些问题,请在解压缩后看到“Messenger Sample”。)

6 个答案:

答案 0 :(得分:12)

除了纯UI任务(例如BooleanToVisibilityConverter)之外,我通常根本不在MVVM中使用转换器。恕我直言,您应该在ContractViewModel中声明CustomerViewModel类型的Customer属性,而不是使用ContractToCustomerConverter

答案 1 :(得分:11)

this conversation中,有一条评论同意Kent的立场,而不是完全使用转换器,这很有趣:

  

ViewModel基本上是类固醇的值转换器。它需要“原始”数据   并将其转换为呈现友好的内容,反之亦然。如果   你发现自己将一个元素的属性绑定到一个ViewModel   财产,你正在使用价值转换器,停止!为什么不创建一个   ViewModel上的属性,公开“格式化”数据,然后删除   价值转换器呢?

this conversation

  

我唯一能看到用途的地方   MVVM中的值转换器   架构是跨元素的   绑定。如果我绑定了   面板对IsChecked的可见性   一个CheckBox,然后我将需要使用   BooleanToVisibilityConverter。

答案 2 :(得分:8)

转换器应该很少与MVVM一起使用。事实上,我努力不使用它们。 VM应该执行视图完成任务所需的所有操作。如果视图需要基于Customer的{​​{1}},则VM上应该有Contract属性,只要Customer发生更改,VM属性就会对其进行更新。

  

这个MVVM模式的一个优点是我还可以将View绑定到ViewModel B,后者用不同的数据填充它。

我对这个说法提出质疑。根据我的经验,视图不是在不同的VM类型之间共享,也不是MVVM的目标。

答案 3 :(得分:5)

对于那些在视图中实际上没有说“非平凡转换器”的人,你如何处理以下内容?

假设我有一个气候传感器模型,它代表在给定位置从各种仪器(气压计,湿度计,温度计等)读取的时间序列。

假设我的视图模型从我的模型中公开了一个可观察的传感器集合。

我有一个包含WPF工具包DataGrid的视图,它绑定到视图模型,ItemsSource属性设置为可观察的传感器集合。如何为给定的传感器表示每种仪器的视图?通过使用转换器(TimeSeriesToSparklineConverter)显示通过将时间序列转换为图像源而生成的小图(想想Edward Tufte sparkline

以下是我对MVVM的看法:模型将数据公开给View Models。视图模型将行为,模型数据和状态公开给View。视图可以直观地表示模型数据,并为符合视图模型状态的行为提供界面。

因此,我不相信迷你图像在模型中(模型是数据,而不是它的特定视觉表示)。我也不相信迷你图像会出现在视图模型中(如果我的视图想要以不同的方式表示数据,比如显示系列的最小值,最大值,平均值,标准偏差等的网格行?)。因此,在我看来,View应该处理将数据转换为所需表示的工作。

因此,如果我想在命令行界面而不是WPF GUI中公开某些视图模型的行为,模型数据和给定状态,我不希望我的模型或我的视图模型包含图像。这是错的吗?我们是SensorCollectionGUIViewModel还是SensorCollectionCommandLineViewModel?这对我来说似乎不对:我认为视图模型是视图的抽象表示,而不是具体的,并且与这些名称所暗示的特定技术相关联。

这就是我对MVVM不断发展的理解。那么对于那些不使用转换器的人来说,你在这做什么?

答案 4 :(得分:1)

我已经使用Stackoverflow多年了,这是我第一个发布的答案。

我认为转换器属于MVVM中的View,请考虑以下情况:

App由3个团队(webapi团队,webclient团队和UI团队)开发。 UI经常更改,因此webclient团队(从webapi接收数据并将其放入viewmodel)不能总是修改viewmodel来满足UI需求。当UI团队使用不同版本的设计时,这变得不可能。因此,UI团队必须有自己的方式来呈现数据,而解决方案是Converters。

希望这对某人有帮助。

答案 5 :(得分:0)

我会在讨论中加上2美分。

我确实使用转换器,这是有意义的。

说明: 在某些情况下,您需要在UI中以更多方式在Model中表示1个值。我通过1种类型公开了这个值。另一种是通过转换器处理的类型。如果要在VM中通过2个属性公开1个值,则需要手动处理更新通知。

例如,我有一个包含2个整数的模型:TotalCountDoneCount。现在我希望这两个值都显示在TextBlocks中,另外我想显示完成百分比。

我使用DivisionConverter多转换器解决了这个问题,该转换器采用了前面提到的2个。

如果我在VM中有特殊PercentDone,我需要在更新DoneCount时更新此属性。