Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用带有Caliburn Micro屏蔽导体的MEF_C#_Wpf_Mef_Caliburn.micro_Factory Pattern - Fatal编程技术网

C# 使用带有Caliburn Micro屏蔽导体的MEF

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

(TLDR版本如下)我正在设计一个WPF应用程序,其中MEF作为IoC,Caliburn Micro作为框架。应用程序的主窗口如下所示:

以下是窗口的Viewmodel:

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