Mvvm 如何从导体解析屏幕

Mvvm 如何从导体解析屏幕,mvvm,caliburn.micro,Mvvm,Caliburn.micro,我希望用Caliburn.Micro显示的屏幕/视图模型的正确解析方法是什么 以前我一直在使用IWidgetConductor,它维护着IWidget对象的集合(基本上是我的视图模型),我通过查询获得我想要激活的屏幕/视图模型 namespace App { using System; using System.Collections.Generic; using System.Linq; using App.ViewModels; public enu

我希望用
Caliburn.Micro
显示的屏幕/视图模型的正确解析方法是什么

以前我一直在使用
IWidgetConductor
,它维护着
IWidget
对象的集合(基本上是我的视图模型),我通过查询获得我想要激活的屏幕/视图模型

namespace App
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using App.ViewModels;

    public enum WidgetType
    {
        WidgetA,
        WidgetB,
        WidgetC,
    }

    public interface IWidgetMetaData
    {
        WidgetType WidgetType { get; }
    }

    public class WidgetConductor
    {
        private readonly IEnumerable<Lazy<IWidget, IWidgetMetaData>> widgets;

        private readonly DialogViewModel dialogViewModel;

        public WidgetConductor(IEnumerable<Lazy<IWidget, IWidgetMetaData>> widgets, DialogViewModel dialogViewModel)
        {
            this.widgets = widgets;
            this.dialogViewModel = dialogViewModel;
        }

        public IWidget GetWidget(WidgetType widgetType)
        {
            var lazy = this.widgets.FirstOrDefault(e => e.Metadata.WidgetType == widgetType);
            return lazy == null ? null : lazy.Value;
        }

        public object GetWidgetAsDialog(WidgetType widgetType)
        {
            return this.dialogViewModel.ShowDialog(this.GetWidget(widgetType));
        }
    }
}
WidgetConductor
通过其构造函数传递给
Shell
viewmodel

使用
EventAggregator
可以在我的应用程序中的某个地方发布
显示屏幕
事件,在将其传递给
ActivateItem
之前,我从事件处理对象查询
WidgetConductor
,以获得所需的
小部件

var widget = this.widgetConductor.GetWidget(WidgetType.StatusBarViewModel);
ActivateItem(widget);

我觉得我好像绕过了
Caliburn.Micro提供的
导线。是否有一种方法可以使用
导体

ShellViewModel继承
导体.Collection.OneActive
或AllActive来获得相同的结果。OneActive一次允许1个viewmodel,AllActive允许所有viewmodel处于活动状态(例如MDI)

现在,您可以访问名为Items的属性,在您的情况下,该属性是BindableCollection>()(在封面下是ObserableCollection(),但带有AddRange(object x)。通过“ShellViewModel”构造函数上的正常枚举,您可以导入IWidget,就像您在自定义导体上所做的那样

然后您可以填充菜单或控件项

使用
可以显示集合中已经存在的小部件(当然是样式化的),然后使用
和一些基于相关项目的激活代码调用ActivateItem(SomeWidget),单击某种类型的

参考:

注意:参考示例使用MEF作为IoC容器,并且是Silverlight实现的,WPF的关闭策略略有不同。AutoFac应该可以

嗯,


Morgan

如果我继承自
Conductor.Collection.OneActive
ActivateItem()
需要的是一个
惰性
对象,而不是一个视图不存在的
IWidget
。我是否需要覆盖
ActivateItem
或其他什么?是的,可能需要覆盖…这是完全可以理解的,因为您使用了额外的元数据来描述您的小部件。另一种可能性是,您可能需要自从你走了额外的一段路后,稍微简化一下。IWidget是否将IScreen作为继承的接口?或者你的小部件是否继承了Screen,IWidget?
SomeWidget:Screen,IWidget
是我走的路线。然后你应该能够使用Conductor而不出现问题和条目。AddRange(小部件)从您的IEnumerable中,可以看到shell或主视图的构造函数viewmodel。
var widget = this.widgetConductor.GetWidget(WidgetType.StatusBarViewModel);
ActivateItem(widget);