2012-04-26 103 views
0

我正在編寫一個使用MEF和第三方庫MEFedMVVM的WPF應用程序。使用MEFedMVVM在父視圖/視圖模型中實現視圖模型優先方法

我試圖創建一個設計,從而父視圖模型有一個子視圖模型的集合,我希望使用視圖模型優先的方法,因爲這保持視圖模型以外的視圖,從而保持代碼更多視圖以模型爲中心,更多單元可測試。

我已閱讀this discussionthis discussion關於使用DataTemplate進行視圖以及Reed Copsy,Jr的建議here使用通用視圖來查看模型映射資源。但是,我正在努力實現一些有效的工作。

我父母的看法是非常簡單的:

[ExportViewModel("MyParentViewModel")] 
public class MyParentViewModel : ViewModelBase 
{ 
    [ImportingConstructor] 
    public MyParentViewModel() 
    { 
     var myChildVM = ServiceLocator.Current.GetInstance<MyChildViewModel>()); 
    } 
} 

這是孩子視圖模型:

<UserControl x:Class="MyParentView" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:meffed="clr-namespace:MEFedMVVM.ViewModelLocator;assembly=MEFedMVVM.WPF" 
      meffed:ViewModelLocator.ViewModel="MyParentViewModel" /> 

父視圖模型從實現IContextAware基類型派生

[Export(typeof(MyChildViewModel))] 
[ExportViewModel("MyChildViewModel", true)] 
public class MyChildViewModel : ViewModelBase 
{ 
} 

而這有一個相應的視圖:

<UserControl x:Class="MyChildView" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:meffed="clr-namespace:MEFedMVVM.ViewModelLocator;assembly=MEFedMVVM.WPF" 
      meffed:ViewModelLocator.ViewModel="MyChildViewModel" /> 

起初,我還以爲指定的ExportViewModel屬性的第二個布爾參數MyChildViewModel將使用視圖模型,第一種方法使一切工作爲我的觀點和看法車型在視圖MEFed在一起'XAML代碼。然而,事實證明這是不是這樣的,什麼我居然得到傳遞給IContextAware.InjectContext()當我在MyParentViewModel構造函數實例化一個MyChildViewModel對象是MyParentView對象。不是我期待和希望的對象。顯然,我需要添加一些東西來將它們連接起來。任何人都可以提供一個如何做到這一點的例子嗎?

謝謝!

+0

是有一個原因,你正在使用一個服務定位,讓您的孩子VM?爲什麼不用MEF呢? – 2012-04-26 19:23:49

+0

爲什麼'MyChildView'指定'ViewModel =「MyParentViewModel」'? – 2012-04-26 19:25:19

+0

謝謝jberger,愚蠢的錯字 - 已經糾正它。 – Neo 2012-04-30 08:45:10

回答

4

當你真的想用視圖模型一,那麼你應該做的:

[ExportViewModel("MyParentViewModel")] 
public class MyParentViewModel : ViewModelBase 
{ 
    // Create property for your child vm 
    public MyChildViewModel Child {get; private set} 

    // If you do MEF use constructor injection instead of servicelocator 
    [ImportingConstructor] 
    public MyParentViewModel(MyChildViewModel child) 
    { 
     this.Child = child; 
    } 
} 

然後定義一個DataTemplate您childvm

<DataTemplate DataType="{x:Type local:MyChildViewModel}"> 
    <view:MyChildViewUserControl /> 
</DataTemplate> 
在你的MainView你知道

要顯示孩子的數據,否則你不需要孩子的財產;)所以簡單地把一個ContentControl放在孩子數據應該去的地方並綁定到你的財產。

例如

<TabControl> 
    <TabItem Header="MyChildData"> 
     <ContentControl Content="{Binding Child}" /> 
    </TabItem> 
</TabControl> 

PS:代碼寫入沒有IDE,所以錯誤的可能:)

+0

非常感謝,非常清楚。但是,在實現這一點之後,我現在認識到,在MEF與MEFedMVVM一起使用MEF時,視圖模型優先方法可能是一個壞主意。我有效地規避了MEFedMVVM的內置導出/導入條款,它們連接了視圖和視圖模型,而是使用標準WPF內部結構通過DataType設置了DataTemplates。我認爲這樣做很好,因爲它使視圖不受視圖模型影響,但如果設計允許,則可以使用視圖優先方法並在視圖模型中注入或實例化視圖。 – Neo 2012-04-30 16:18:19