2012-04-19 11 views
1

私は2つのアプリケーションを持っています.1つはメインアプリケーションで、もう1つはデザイナーフォームアプリケーションです。View用のViewModelを別のViewModelに置き換えます。

現在のところ、私の主なアプリケーションはプリズムとmefで作業しています。私の主なアプリケーションのビューの一部は、データ入力フォームです。デザイナーフォームアプリケーションから私が望むのは、データ入力フォームビューをロードして編集できるようにすることですが、これを行うには設計目的に別のビューモデルを使用したいと考えています。フォームを通常のビューモデルに付けてデータなどを取得しようとしません。

MEFを使用すると、通常のビューモデルではなく別のエクスポートを提供することができますか?理想的には、メインアプリケーションのviewmodelを置き換えるだけなので、代わりにそれを使用します。

これは私の例の図であり、のviewmodel

[Export("PatientDetailView")] 
[PartCreationPolicy(CreationPolicy.NonShared)] 
public partial class PatientDetailView : UserControl 
{ 
    [ImportingConstructor] 
    public PatientDetailView(PatientDetailViewModel viewModel) 
    { 
     InitializeComponent(); 

     this.DataContext = viewModel; 
    } 
} 

そして、ここをインポートすると、私のviewmodelの基礎である:

[Export(typeof(PatientDetailViewModel))] 
[PartCreationPolicy(CreationPolicy.NonShared)] 
public class PatientDetailViewModel : ViewModelBase, IRegionManagerAware 
{ 
    [ImportingConstructor] 
    public PatientDetailViewModel(IEventAggregator eventAggregator, IDialogService dialogService, IRegionManager regionManager) 
     : base(eventAggregator, dialogService, regionManager) 
    { 
     //Contains Commands etc for Saving Patient Detail Record 
     //Receiving patient detail etc 
    } 

}

UPDATE:

ザ・上記は患者モジュールに含まれているアセンブリ。これは、メインアプリケーションのためにどのように動作するのでしょうか。 Designerアプリケーションのために私は以下のようなもので上記のビューモデルを置き換えたい:上記の私のメインのアプリケーションのデフォルトの動作をオーバーライドするために取り組んでいる

[Export(typeof(PatientDetailViewModel))] 
[PartCreationPolicy(CreationPolicy.NonShared)] 
public class PatientDetailViewModel : ViewModelBase, IRegionManagerAware 
{ 
    [ImportingConstructor] 
    public PatientDetailViewModel(IEventAggregator eventAggregator, IDialogService dialogService, IRegionManager regionManager) 
     : base(eventAggregator, dialogService, regionManager) 
    { 
     //Contains Commands etc for Designing the form 
     //No commands from the original VM so changes how it tries to work. 
    } 

}

。このVMは、Designerアセンブリまたは別のDesignerVMsアセンブリに含まれます。

答えて

0

これらは別々のアプリケーションであり、datacontextは任意のオブジェクトである可能性があるため、解決策は簡単です。

ビューが変更され、データコンテキストが名前でインポートされます。あなたが本当にそこにまだ芋の最良の選択肢である別々のアセンブリ(、できない場合は、更新を

public static class MefContracts 
{ 
    public const string PatientDetailViewModel = "PatientDetailViewModel"; 
} 

[Export("PatientDetailView")] 
[PartCreationPolicy(CreationPolicy.NonShared)] 
public partial class PatientDetailView : UserControl, IPartImportsSatisfiedNotification 
{ 
    [Import(MefContracts.PatientDetailViewModel, typeof(object)] 
    private object vm; 

    public void OnImportsSatisfied() 
    { 
    this.DataContext = vm; 
    } 


    public PatientDetailView() 
    { 
    InitializeComponent(); 
    } 
} 

は、次に、アプリケーションに応じて、あなただけのあなたが欲しいのViewModelが含まれており、それが

[Export(MefContracts.PatientDetailViewModel, typeof(object)))] 
[PartCreationPolicy(CreationPolicy.NonShared)] 
public class PatientDetailViewModel : ViewModelBase, IRegionManagerAware 
{ 
    .... 
} 

名前でエクスポートVmをインポートする代わりに、VMを作成できるファクトリをインポートします。どちらが作成するかは、各アプリで異なる設定値にする必要があります。別の契約でvmsをエクスポートする必要があります。そうでなければ、それらを区別するための(簡単な)方法はありません。例:

public static class MefContracts 
{ 
    public const string PatientDetailViewModelMain = "PatientDetailViewModelMain"; 
    public const string PatientDetailViewModelDesigner = "PatientDetailViewModelDesigner"; 
} 

//the main vm 
[Export(MefContracts.PatientDetailViewModelMain, typeof(object)))] 
[PartCreationPolicy(CreationPolicy.NonShared)] 
public class PatientDetailViewModel : ViewModelBase, IRegionManagerAware 
{ 
    .... 
} 

//the other vm 
[Export(MefContracts.PatientDetailViewModelDesigner, typeof(object)))] 
[PartCreationPolicy(CreationPolicy.NonShared)] 
public class OtherPatientDetailViewModel : ViewModelBase, IRegionManagerAware 
{ 
    .... 
} 

[Export("PatientDetailView")] 
[PartCreationPolicy(CreationPolicy.NonShared)] 
public partial class PatientDetailView : UserControl 
{ 
    [ImportingConstructor] 
    public PatientDetailView(PatientDetailViewModelFactory viewModelFactory) 
    { 
    InitializeComponent(); 
    this.DataContext = viewModelFactory.Create(); 
    } 
} 

[Export] 
class PatientDetailViewModelFactory 
{ 
    [Import] 
    private CompositionContainer container{ get; set; } 

    public enum AppType{ Main, Designer } 

    public AppType AppType{ get; set; } 

    public object Create() 
    { 
    return container.GetExportedValue<object>( 
     AppType == AppType.Main ? MefContracts.PatientDetailViewModelMain : 
           MefContracts.PatientDetailViewModelDesigner); 
    } 
} 
+0

返信いただきありがとうございます。私の問題は、私が望むViewModelだけをどのように含めるかわかりません。 他のVMをデザイナーアプリケーションでエクスポートすることはできますが、2つのエクスポートがあります。このエクスポートを新しいものに置き換えることはできますか? –

+0

あなたは別々のアセンブリに各VMを置くことはできませんし、それらのアセンブリの1つだけをアプリケーションごとに含めることはできませんか? – stijn

+0

実際、ViewModelは、同じアセンブリ内でViewとともに移動する必要があります。このモジュールの一部ですが、設計者の目的のために、別のアセンブリでは少し間違っているように見えます。私は、MEFがホットスワッピングコンポーネントのすべてであると思っていました。 –

0

すると、このような何かを試してみてください:

あなたのビューモデルを定義するインタフェースの作成:インタフェースから、あなたのビューモデルを導出し、エクスポート属性を変更しますでは、メインアプリケーションを

public interface IPatientDetailViewModel{...} 

を。

[Export(typeof(IPatientDetailViewModel)] 
public class PatientDetailViewModel : ViewModelBase, 
    IRegionManagerAware, IPatientViewModel 
{ ... } 

私はビューが共有アセンブリ内にあると仮定します。 (デザインのアプリでMEFを使用していない場合)あなたのビューに既定のコンストラクタを追加し、インターフェイスを使用するには、インポート変更:今すぐ

public PatientDetailView() 
{ 
    InitializeComponent(); 
} 

[ImportingConstructor] 
public PatientDetailView(IPatientDetailViewModel viewModel) 
{ 
    InitializeComponent(); 

    this.DataContext = viewModel; 
} 

を、あなたのデザイナーのアプリがMEFを使用している場合は、別のビューモデルをエクスポートすることができますMEFを使用してビュー

[Export(typeof(IPatientDetailViewModel)] 
public class DesignPatientDetailViewModel : ViewModelBase, IPatientViewModel 
{ ... } 

かそうでない場合にインポートするビューのXAMLで

d:DataContext="{d:DesignInstance local:DesignPatientViewModel}" 

を使用しています。

関連する問題