2009-06-17 70 views
17

假设我有一个视图绑定到ViewModel A其中有一个可观察的集合Customers如何在MVVM模式中使用WPF转换器?

此MVVM模式的一个优点是,我还可以将视图绑定到使用不同数据填充它的视图模型。

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

这样做的问题是转换器存在MVVM模式之外,因此不知道我的视图模型具有其它来源的客户。

  • 是那里的查看的方式来视图模型传递到转换器,使其参与的MVVM模式提供分开呢?
  • 有没有办法让我以某种方式在我的ViewModel中包含Converter,以便转换器使用ViewModel提供的当前依赖关系?
  • 或转换器只是荣耀代码隐藏,因此不在MVVM模式中使用,所以如果您使用MVVM,那么你只需创建自己的“转换器”(你的ViewModel类的方法),它返回像Image对象,可见性对象,FlowDocuments等等,以便在视图上使用,而不是使用转换器?

(我看到在随附MVVM Template Toolkit download的WPF演示应用程序的使用转换器后,就对这些问题,请参阅“信使示例”拆包后)。

回答

8

转换器应该很少是与MVVM一起使用。事实上,我努力不使用它们。虚拟机应该完成视图完成任务所需的一切。如果视图需要基于ContractCustomer,则每当Contract更改时,虚拟机上应该有一个由VM逻辑更新的Customer属性。

此MVVM模式的一个优点是,我也可以将视图绑定到视图模型B,视图模型B用不同的数据填充它。

我对这种说法提出异议。根据我的经验,视图不是跨不同的VM类型共享的,也不是MVVM的目标。

+3

好的我认为你不应该在不同的虚拟机之间共享你的观点,但是一个ViewModel应该能够被不同的视图共享,因此MVVM的可测试性的好处,对吧?您应该能够将模拟视图和模拟模型连接到ViewModel,以确保从模拟模型接收到的所有数据组合都能生成暴露给视图的正确属性值。你会同意吗? – 2009-06-17 15:07:26

12

我通常在MVVM中完全不使用转换器,纯粹的UI任务除外(例如BooleanToVisibilityConverter)。恕我直言,你倒是应该申报类型CustomerViewModel的顾客财产在你ContractViewModel,而不是使用ContractToCustomerConverter

11

this conversation存在与肯特的位置一致,不使用转换器在所有的评论,有趣的:

一个ViewModel基本上是一个类固醇的价值转换器。它需要“原始”数据 并将其转换为表示友好的东西,反之亦然。如果 您曾经发现自己将元素的属性绑定到ViewModel的 属性,并且您正在使用值转换器,请停止!为什么不在视图模型上创建一个 属性来暴露“格式化”的数据,然后完全删除 值转换器?

而在this conversation

我可以看到在MVVM 架构 值转换器使用一个唯一的地方是跨元件 绑定。如果我绑定 能见度小组,CheckBox的 器isChecked的,那么我将需要使用 的BooleanToVisibilityConverter。

5

对于那些有效地说在视图中没有“非平凡转换器”的人,你如何处理以下问题?

比方说,我有一个表示时间序列从给定的位置,各种仪器仪表(晴雨表,湿度计,温度计等)读数的气候传感器的型号。

比方说,我的视图模型公开从我的模型中的传感器可观察到的集合。

我有一个包含WPF Toolkit DataGrid的视图,该视图绑定到视图模型,ItemsSource属性设置为可观察的传感器集合。如何表示给定传感器的每台仪器的视图?通过显示小图(认为爱德华托佛特sparkline这里),其是通过使用一个转换器(TimeSeriesToSparklineConverter

这里是我认为MVVM的时间序列变换为图像源产生:模型暴露的数据查看模型。视图模型将行为,模型数据和状态暴露给视图。视图可以直观地表达模型数据,并为与视图模型状态一致的行为提供界面。

正是如此,我不相信,所述火花图像模型去(型号是数据,而不是它的一个特定的可视化表示)。我也不认为sparkline图像会出现在视图模型中(如果我的视图想要以不同的方式表示数据,比如表示网格的行,只显示系列的最小值,最大值,平均值,标准偏差等)。因此,在我看来,视图应该处理将数据转换为所需表示的工作。

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

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

+3

我看到你描述的问题是这样的:使用一个值转换器,你将制作一个ClimateSensorToSparklineGraphConverter,它需要收集一系列气候传感器并输出图像。对于像创建位图图像这样的东西,您不会使用DataTemplate和包含ViewModel的ViewModel集合来完成此操作,在某些情况下,您需要使用C#代码来创建图像。在转换器中,您也可以访问例如一个Users集合来确定当前用户被允许看到的内容。这会打破MVVM,因为ViewModel应该有用户注入。 – 2009-06-18 07:51:59

0

我会在这个讨论中加2美分。

我使用转换器,它是有道理的。

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

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

我解决这个使用DivisionConverter多转换器,它采用2前面提到的整数。

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

+0

你基本上是通过声明转换器来更新PercentDone属性,并在绑定抛出propertychanged时触发它,只有它由具有函数的类表示,而不是属性...因此,我不认为这是实际的好的使用案例。我认为纯粹的UI到UI的东西保证转换器。 – Joris 2011-07-05 00:32:05