2012-04-26 10 views
0

MEFとMEFedMVVMというサードパーティのライブラリを使用してWPFアプリケーションを作成しています。MEFedMVVMを使用して親ビュー/ビューモデル内にビューモデルを先に実装する方法

親ビューモデルに子ビューモデルのコレクションが含まれているデザインを作成しようとしていますが、これはビューモデル以外の方法でビューを保持してコードを保持するため、より多くのモデルを中心とし、より多くのユニットをテストすることができます。

私はビューのためのDataTemplateを使用してに関するthis discussionthis discussionを読んだことがある、ともリードCopsy、ジュニアの提案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" /> 

は当初、私は私の意見とビューモデルをビューで一緒にMEFedされているようMyChildViewModelためExportViewModel属性上の第2のBooleanパラメータを指定すると、ビューモデルの最初のアプローチを使用して、すべての仕事をするだろうと思いました'XAMLコード。しかし、これはそうではない、と私はMyParentViewModelコンストラクタでMyChildViewModelオブジェクトをインスタンス化するとき、私は実際にIContextAware.InjectContext()に渡さを取得するMyParentViewオブジェクトで判明。 MyChildViewオブジェクトは私が期待していたと期待していた。明らかに、私は一緒にワイヤリングするために何かを追加する必要があります。誰でもこれを行う方法の例を提供できますか?

ありがとうございます!

+0

あなたの子供VMを取得するためのServiceLocatorを使用している理由はそこにある、IDEなしで書かれていますか?なぜそれをMEFしないのですか? –

+0

'MyChildView'で' ViewModel = "MyParentViewModel" 'を指定するのはなぜですか? –

+0

ありがとうございましたjberger、愚かなタイプミス - それを修正しました。 – Neo

答えて

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; 
    } 
} 

、あなたのchildvmのためにあなたがしたい場所がわからあなたMAINVIEWで

<DataTemplate DataType="{x:Type local:MyChildViewModel}"> 
    <view:MyChildViewUserControl /> 
</DataTemplate> 

をするDataTemplateを定義します子データを表示する必要があります。そうしないと、子プロパティは必要ありません;)単純にContentControlを配置して、子データを移動してプロパティにバインドする必要があります。

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

PS:コードは、エラーの可能なので:)

+0

これはありがとうございました。しかし、これを実装したところ、MEFをMEFedMVVMで使用すると、ビュー・モデル・ファースト・アプローチが悪いアイデアになることがあります。私は、MEFedMVVMの組み込みのエクスポート/インポートの規定を迂回して、ビューをワイヤリングし、モデルを表示し、標準のWPF内部を使用してDataTypeを設定したDataTemplatesでワイヤリングすることを効果的に回避しています。ビューのモデルをビューのままに保つという点で、これがうまくいくと思いますが、ビューファーストのアプローチを使用し、ビューモデルでビューを注入またはインスタンス化することは、設計上許されていれば受け入れられます。 – Neo

関連する問題