2010-11-10 79 views
6

我玩過Model-View-ViewModel的一些不同實現,並且一直遇到一種情況,我不確定正確的處理方式。我知道MVVM的目標之一是將View從應用程序邏輯中分離出來,以便可以在沒有View的情況下測試邏輯。將邏輯放在與View沒有依賴關係的ViewModel中解決了這個問題。大。更好的是,如果模型可以從ViewModel中分離出來,那麼它可以被嘲弄。EF4 + MVVM - 在ViewModel中公開實體?

所以我的問題是,如果ViewModel解耦模型從視圖?換句話說,是否可以通過ViewModel將EntityFramework實體展示給視圖?例如,假設在視圖中有一個組合框,用戶可以爲一個地址選擇一個狀態。在AddressViewModel中,應該將State公開爲真實體類型屬性,還是應該將其公開爲StateViewModel?如果它應該是StateviewModel類型的屬性,我不明白如何在AddressViewModel.State設置器中管理底層模型(因爲屬性中設置的是StateViewModel而不是State實體)。

在我看來,這可能無論如何,但似乎更一致,永遠不會將模型直接暴露給視圖。思考?

回答

2

視圖模型的目的是將視圖與數據模型分離。如果視圖中沒有與數據模型耦合的功能,則不需要視圖模型。

如果在其屬性它的創建後不改變,而數據模型中的對象,該視圖不會修改,而且可以在用戶界面不進行格式化或轉換呈現,那麼你不要將其任何功能直接暴露給視圖。你不需要這個視圖模型。

在你的例子中,你可能不會創建一個StateViewModel類,因爲這樣的類不會真的做任何事情。

+0

這在理論上是正確的,但實際上有時事情並不像人們(其中的開發人員)想要的那樣持續不變,例如,未來可能會擴展狀態列表以包含其他國家等。 .. – 2010-11-11 05:38:44

+1

這不是那種會對此決定產生影響的變化。向列表中添加新狀態不會創建要求其屬性在UI中可編輯的要求。 – 2010-11-11 22:05:31

4

你應該努力將你的模型與你的觀點完全分離,這應該是一個目標,你可能會遇到它,或者你可能不會,但仍然應該是你的目標。

具體來說,你的問題處理常量列表(或多或少),這是一個簡單的例子。糾正我,如果我在這裏錯了,但你可能有一個States表,codename爲每個國家,然後你有另一個表與前者的外鍵。

在這種情況下,最好是整個應用程序加載和應用程序初始化期間創建一次StateViewModel列表,然後用外鍵值處理(狀態code因爲它是),而不是StateViewModel對象本身。你應該使用的屬性是SelectedValueComboBox,例如SelectedValuePath

<ComboBox ItemsSource="{x:Static StateViewModel.StaticList}" 
      SelectedValue="{Binding StateForeignKey}" 
      SelectedValuePath="code" 
      DisplayMemberPath="name" /> 

這將填充ComboBoxStateViewModel對象(用一個現在佈置的環境中創建的),但會通過所選項目的code財產到綁定字段StateForeignKey,此外,ComboBox將顯示name屬性,以便它是人類可讀的。

0

你不能在視圖模型暴露實體的原因是因爲你不應該視污染實體特定代碼如IDataErrorInfo的,INotifyPropertyChanged的,IEditableObject等

實體是應用的核心,應該是POCO,可以在任何類型的應用程序中重用。例如,如果您開發可通過移動,Web和桌面訪問的應用程序,則不需要爲每種類型的應用程序創建實體。

解耦原因?對不起,但我不同意,因爲我沒有看到任何有益的解耦模型和ViewModel,因爲單元測試可以在ViewModel中使用或不使用Entity。

UPDATE

對不起,我忘了你使用EF4。 EF4實體默認支持INotifyPropertyChanged,所以在ViewModel上暴露實體是可以接受的。

1

我通過viewmodel將實體直接綁定到我的視圖,除非我必須爲treeview添加特定的屬性,如IsSelected等等。如果我必須添加附加屬性,那麼我有viewmodel包裝每個實體屬性。