C# 使用带有Caliburn Micro屏蔽导体的MEF
(TLDR版本如下)我正在设计一个WPF应用程序,其中MEF作为IoC,Caliburn Micro作为框架。应用程序的主窗口如下所示: 以下是窗口的Viewmodel:C# 使用带有Caliburn Micro屏蔽导体的MEF,c#,wpf,mef,caliburn.micro,factory-pattern,C#,Wpf,Mef,Caliburn.micro,Factory Pattern,(TLDR版本如下)我正在设计一个WPF应用程序,其中MEF作为IoC,Caliburn Micro作为框架。应用程序的主窗口如下所示: 以下是窗口的Viewmodel: [Export(typeof(MainViewModel))] class MainViewModel : Conductor<PropertyChangedBase>, IHandle<ViewModelType> { private readonly IEventAggregator _e
[Export(typeof(MainViewModel))]
class MainViewModel : Conductor<PropertyChangedBase>, IHandle<ViewModelType>
{
private readonly IEventAggregator _eventAggregator;
private IEnumerable<Screen> _screenList { get; set; }
[ImportingConstructor]
public MainViewModel(IEventAggregator eventAggregator, [ImportMany]IEnumerable<Screen> screenList)
{
_screenList = screenList;
_eventAggregator = eventAggregator;
_eventAggregator.Subscribe(this);
ShowMenu();
}
public void Handle(ViewModelType message)
{
ActivateItem(_screenList.FirstOrDefault(c => c.GetType() == message.VMtype));
DisplayName = "B.I. Surgical & Dressing - " + (ActiveItem as Screen)?.DisplayName;
NotifyOfPropertyChange(() => CanShowMenu);
}
public void ShowMenu() => _eventAggregator.PublishOnUIThread(new ViewModelType(typeof(Menu.MenuViewModel)));
public bool CanShowMenu => ActiveItem.GetType() != typeof(Menu.MenuViewModel);
}
但是,我面临的问题是,当我单击菜单ViewModel
中的一个按钮时,我没有得到一个新的VM,而是一次又一次地得到一个单独的实例,这实际上是预期的,因为此行每次都会找到ViewModel的单独实例:
ActivateItem(_screenList.FirstOrDefault(c=>c.GetType()==message.VMtype))代码>
但是,每当视图被停用时,我都需要处理ViewModel(我想我必须使用Screen类的OnDeactivate方法)。但我不知道如何每次从\u屏幕列表
获取ViewModel的新实例。我的想法是创建某种工厂,但我不知道如何使用MEF实现它,也不知道如何在视图停用时处理ViewModel
短版本:
-TLDR-
在MEF中,我可以有如下内容:
private IEnumerable<Screen> _screenList { get; set; }
[ImportingConstructor]
public MainViewModel(IEventAggregator eventAggregator, [ImportMany]IEnumerable<Screen> screenList)
{
_screenList = screenList;
}
private IEnumerable\u屏幕列表{get;set;}
[导入构造函数]
公共主视图模型(IEventAggregator事件聚合器,[ImportMany]IEnumerable屏幕列表)
{
_屏幕列表=屏幕列表;
}
这将导入所有标有[Export(typeof(Screen))]
属性的组件。但是,这些组件中的每一个都用一些其他属性标记,例如[Export(typeof(ViewModelX))]
。基本上,Screen
是派生每个ViewModel的基类
在我的应用程序中,我使用的是\u屏幕列表
,如下所示:
ActivateItem(_screenList.FirstOrDefault(c=>c.GetType()==typeof(ViewModelX))代码>
但是,在我的问题中,我希望\u screenList
每次都返回一个ViewModelX
的新实例。我该怎么做?终于找到了问题的解决方案。使用ExportFactory
解决了问题
实施情况如下:
private IEnumerable<ExportFactory<Screen>> _screenList { get; set; }
[ImportingConstructor]
public MainViewModel(IEventAggregator eventAggregator, [ImportMany] IEnumerable<ExportFactory<Screen>> screenList)
{
_screenList = screenList;
_eventAggregator = eventAggregator;
_eventAggregator.Subscribe(this);
ShowMenu();
}
public void Handle(ViewModelType message)
{
ActivateItem(_screenList.FirstOrDefault(c => c.CreateExport().Value.GetType() == message.VMtype).CreateExport().Value);
}
private IEnumerable\u屏幕列表{get;set;}
[导入构造函数]
公共主视图模型(IEventAggregator事件聚合器,[ImportMany]IEnumerable屏幕列表)
{
_屏幕列表=屏幕列表;
_eventAggregator=eventAggregator;
_eventAggregator.Subscribe(此);
ShowMenu();
}
公共无效句柄(ViewModelType消息)
{
ActivateItem(_screenList.FirstOrDefault(c=>c.CreateExport().Value.GetType()==message.VMtype.CreateExport().Value);
}
private IEnumerable<ExportFactory<Screen>> _screenList { get; set; }
[ImportingConstructor]
public MainViewModel(IEventAggregator eventAggregator, [ImportMany] IEnumerable<ExportFactory<Screen>> screenList)
{
_screenList = screenList;
_eventAggregator = eventAggregator;
_eventAggregator.Subscribe(this);
ShowMenu();
}
public void Handle(ViewModelType message)
{
ActivateItem(_screenList.FirstOrDefault(c => c.CreateExport().Value.GetType() == message.VMtype).CreateExport().Value);
}