2009-06-17 72 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