我有两个应用程序,一个是主应用程序,另一个是设计器表单应用程序。
目前,我的主要应用程序正在使用prism和mef。我的主要应用程序中的一些视图只是数据输入表单。我想从我的设计器表单应用程序中加载一个数据输入表单视图,然后可以对其进行编辑,但为了做到这一点,我想使用不同的viewmodel进行设计。我不希望表单附加到它通常的viewmodel并尝试获取数据等。
如何使用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
}
}
更新
以上内容包含在患者模块组件中。这适用于主应用程序的应用方式。对于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 :(得分:0)
因为这些是单独的应用程序,而datacontext可以是任何对象,所以解决方案可以很简单。
视图已更改为按名称导入其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没有任何问题),你可以使用简单的工厂代替(到抽象获取ViewModel的方式):导入可以创建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 );
}
}
答案 1 :(得分:0)
尝试这样的事情:
创建一个定义视图模型的界面:
public interface IPatientDetailViewModel{...}
在主应用程序中,从界面派生您的视图模型并修改Export属性。
[Export(typeof(IPatientDetailViewModel)]
public class PatientDetailViewModel : ViewModelBase,
IRegionManagerAware, IPatientViewModel
{ ... }
我假设视图位于共享程序集中。在视图中添加默认构造函数(如果未在设计应用程序中使用Mef),并更改导入以使用界面:
public PatientDetailView()
{
InitializeComponent();
}
[ImportingConstructor]
public PatientDetailView(IPatientDetailViewModel viewModel)
{
InitializeComponent();
this.DataContext = viewModel;
}
现在,如果您的设计器应用使用MEF,则可以导出要导入到视图中的其他视图模型
[Export(typeof(IPatientDetailViewModel)]
public class DesignPatientDetailViewModel : ViewModelBase, IPatientViewModel
{ ... }
或者如果不使用MEF使用
d:DataContext="{d:DesignInstance local:DesignPatientViewModel}"
在你视图中的Xaml。