2011-04-14 29 views
1

基本上,我有以下情形:WPF DataTemplate/DataTemplateSelector - 由2個不同視圖使用的ViewModel的最佳方法?

視圖模型:FooViewModel : BaseViewModelBarViewModel : BaseViewModel
瀏覽:MainViewFooViewBarView

現在我 「注入」 的觀點,並使用DataTemplateDataTemplateSelector設置DataContext。很顯然,我的ItemsControlItemSource綁定到一個ObservableCollection<BaseViewModel>其中包含(現在)一個FooViewModel的實例和BarViewModel

的問題是我想介紹一個AlternateFooView,我想利用相同FooViewModel。我想我會創建另一個DataTemplate並讓我的DataTemplateSelector返回它,但需要有特殊的邏輯來確定要返回哪個DataTemplate(我不能只是通過哪個ViewModel返回),這意味着我必須在BaseViewModel中有某種類型的屬性或字段。我不知道這是否是一個好主意,因爲這似乎是在ViewModel中引入了一個只用於選擇視圖的字段/屬性。它不會傷害我的單元測試,但包含一個字段只是爲了幫助決定選擇哪個UI視圖,看起來很浪費。我不認爲它打破了MVVM,但我很好奇,如果有人有更好的想法?替代的想法我有我不喜歡甚至更多...

理念#2:
- 打開FooViewModel成一個基類,2個不同的FooViewModel的延伸(即BaseFooViewModel,FooViewModel,DifferentFooViewModel)。這看起來很愚蠢,因爲FooViewModel和DifferentFooViewModel除了它們的類類型之外沒有任何區別。

想法#3:
- 只需複製FooViewModel並使其成爲FooViewModel2(它將完全等同於FooViewModel)。這似乎比想法#2更糟糕。


採樣代碼(顯然調整):

public abstract class BaseViewModel : NotificationObject 
{ 
    //Common Stuff 
} 

public abstract MainViewModel : NotificationObject 
{ 
    public MainViewModel() 
    { 
     MyItems = new ObservableCollection<BaseViewModel>() 
     { 
      new FooViewModel(); 
      new BarViewModel(); 
      new FooViewModel(); //New Item -- I want it to use the DifferentFooView 
     } 
     //Load items from a DAL later 
    } 

    public ObservableCollection<BaseViewModel> MyItems { get; set; } 

    //Other Stuff 
} 

<l:MyItemsControl ItemSource={Binding MyItems} ContentTemplateSelector={StaticResource MyTemplateSelector} /> 


謝謝!

+1

如果我缺少任何東西,請糾正我。 你想什麼時候使用AlternateFooView和FooView? 替代項目? – krishnaaditya 2011-04-14 18:10:11

+0

嗯,原本我在想,不同的視圖將取決於什麼是最初加載到ViewModel本身。我認爲你的問題實際上可以幫助很多...也許在現有的DataTemplate上有一個DataTrigger來選擇不同的View而不是2個不同的DataTemplats? – 2011-04-14 18:17:24

回答

4

我同意krishnaaditya這個問題真的歸結爲基於ViewModel的狀態決定使用哪個視圖。這種類型的邏輯通常放置在模板選擇器中,這非常有效。如果您不想將該邏輯放入模板選擇器,請考慮使用我的Routed Template Selection方法對其進行外部化。這使得通過使用路由事件委派模板選擇邏輯變得容易。

你在你的評論中提出的關於使用DataTrigger的想法也可以工作,但是這重新引入了對虛擬機對象的一個​​屬性的需求,該屬性指出加載哪個視圖(你說你不想要)。在我看來,這不一定是壞事。

+0

我很榮幸能回答我的問題(你有這個聲望)。雖然我並不完全反對在VM中擁有一個屬性來指示要選擇哪個DataTemplate的想法,但我不確定這是否違反了MVVM的最佳實踐或慣例。而且,我也喜歡那個RoutedTemplateSelection類。看起來像是一件可能使用的好東西。 – 2011-04-14 19:19:02

+0

此外,我想DataTrigger作爲一種方法來避免虛擬機上的特殊屬性,因爲視圖是由ViewModel的初始狀態決定的,所以我可以將它設置爲從一個已經存在的屬性的一次綁定ViewModel。 – 2011-04-14 19:21:07

+1

@myermian,如果虛擬機已經有一個屬性可以用來確定加載哪個視圖,那麼你就在街上。無論使用模板選擇器還是數據觸發器,都取決於您的偏好。 – 2011-04-14 19:52:41

相關問題