如何从Conductor解析屏幕

时间:2014-11-04 10:18:02

标签: mvvm caliburn.micro

解决我希望用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));
        }
    }
}

我将Widget注册到我的IoC容器(Autofac)中:

            builder.RegisterType<WidgetConductor>()
                   .AsSelf()
                   .SingleInstance();
            builder.RegisterMetadataRegistrationSources();
            builder.Register(e => new StatusBarViewModel(e.Resolve<EventAggregator>()))
                   .As<IWidget>()
                   .WithMetadata<IWidgetMetaData>(e => e.For(m => m.WidgetType, WidgetType.StatusBarViewModel));

WidgetConductor通过其构造函数传递给Shell viewmodel。

可以使用display screen在我的应用中的某个地方发布EventAggregator个事件,并在事件处理对象中查询WidgetConductor所需的Widget,然后再传递到ActivateItem

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

我觉得好像绕过了Conductor提供的Caliburn.Micro。有没有办法使用Conductor获得相同的结果?

1 个答案:

答案 0 :(得分:0)

ShellViewModel继承Conductor<Lazy<IWidget, IWidgetMetaData>>.Collection.OneActive或AllActive。 OneActive一次允许1个视图模型,AllActive允许所有视图模型处于活动状态(例如MDI)。

您现在可以访问名为Items的属性,在您的情况下是BindableCollection&gt;()(在ObserableCollection()的下面,但是使用AddRange(对象x)。通过“ShellViewModel”构造函数的常规枚举,您可以导入IWidget,就像你已经使用自定义导体一样......

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

使用<ItemsControl x:Name="Items" />可以显示集合中已存在的小部件(当然是样式化的),然后使用<ContentControl x:Name="ActiveItem" />和一些基于相关项的激活码调用ActivateItem(SomeWidget),点击一些排序...

参考:https://github.com/Caliburn-Micro/Caliburn.Micro/blob/master/samples/Caliburn.Micro.HelloScreens/Caliburn.Micro.HelloScreens/

http://caliburnmicro.com/documentation/

注意:参考示例使用MEF作为IoC容器并且实现了Silverlight,对于WPF,关闭策略略有不同。 AutoFac应该没问题。

HTH,

摩根