Caliburn.Micro:使用Conductor在页面之间移动:如何从子类调用父类方法或属性?

时间:2017-02-15 14:03:59

标签: wpf mvvm autofac caliburn.micro conductor

这是我的主要父类ViewModel:

[AutofacRegisterType(PAGE_NAME, typeof(IMainPage), IsSingleInstance = false)]
public class MainPageViewModel : MainPageViewModelBase
{
    public const string PAGE_NAME = "MainPage";

    public MainPageChildsConductor ChildPages { get; private set; }

    public IMainPageChild ActiveChildPage
    {
        get { return ChildPages.ActiveItem; }
    }

    public MainPageViewModel()
    {
        PageName = PAGE_NAME;
        DisplayName = PAGE_NAME;

        DisposeOnDeactivate = true;

        InitChildPages();
    }

    private void InitChildPages()
    {
        ChildPages = new MainPageChildsConductor();
        ChildPages.Parent = this;
        ChildPages.ConductWith(this);

        var trallchilds = TypeRegistry.GetItemsByType<IMainPageChild>();
        var trchilds = trallchilds.Where(p => p.AutoRegister != null && p.AutoRegister.Name.StartsWith(PAGE_NAME + ":")).ToList();

        var childs = new List<IMainPageChild>();
        foreach (var trchild in trchilds)
        {
            var child = trchild.CreateType<IMainPageChild>();
            childs.Add(child);
        }

        childs.Sort((a, b) => a.PageIndex.CompareTo(b.PageIndex));
        ChildPages.Items.AddRange(childs);

        ChildPages.ActivateWith(this);
        ChildPages.DeactivateWith(this);
    }
}

这是我的一个子类ViewModel:

[AutofacRegisterType(PAGE_NAME, typeof(IMainPageChild), IsSingleInstance = false)]
public class Child1PageViewModel : MainPageChildViewModelBase
{
    public const string PAGE_NAME = "ChildPage:Child1Page";
    public const int PAGE_INDEX = 30;

    public Child1PageViewModel()
    {
        PageName = PAGE_NAME;
        DisplayName = "Child1";
        PageIndex = PAGE_INDEX;

        InitButtons();
        InitSummaryData();
    }
}

这是继承Caliburn.Micro类导体的类:

public class MainPageChildsConductor : Conductor<IMainPageChild>.Collection.OneActive
{
    public MainPageChildsConductor()
    {
    }

    public override void NotifyOfPropertyChange([CallerMemberName] string propertyName = null)
    {
        base.NotifyOfPropertyChange(propertyName);

        if (Parent is INotifyPropertyChangedEx)
            ((INotifyPropertyChangedEx)Parent).Refresh();
    }
}

问题是:如何调用父页面中存在的方法或属性&#39; MainPageViewModel&#39;从子页面&#39; Child1PageViewModel&#39; ???

1 个答案:

答案 0 :(得分:0)

您的子视图需要从Screen继承,并且在父视图模型中激活后,您将通过从Screen继承来获取对子VM的Parent属性的引用。

有关详细信息,请参阅文档中的此页面: Screens, Conductors and Composition

这就是我在其中一个项目中的表现:

public class MainViewModel : Conductor<IScreen>.Collection.OneActive, IHandle<CreateNewGraphEvent>, IHandle<AddMeasurementsToGraphEvent>, IHandle<DeleteNamedGraphEvent>,
    IHandle<GraphRenamedEvent>, IHandle<AddDuplicateGraphEvent>
{
    private readonly TreeListViewModel _TreeView;
    private readonly StatusBarViewModel _StatusBar;
    private readonly IEventAggregator _Aggregator;
    private readonly ProgressDialogViewModel _Progress;

    public MainViewModel(IEventAggregator aggregator, TreeListViewModel treeView, StatusBarViewModel statusBar)
    {
        if (aggregator == null)
            throw new ArgumentNullException("aggregator");
        _Aggregator = aggregator;
        _Aggregator.Subscribe(this);

        if (statusBar == null)
            throw new ArgumentNullException("statusBar");
        _StatusBar = statusBar;

        if (treeView == null)
            throw new ArgumentNullException("treeView");
        _TreeView = treeView;
        this.Items.CollectionChanged += Items_CollectionChanged;
    }

    public void Handle(CreateNewGraphEvent message)
    {
        ChartViewModel document = IoC.Get<ChartViewModel>(message.SelectedGraphType.ToString());
        if (document == null) return;
        document.DisplayName = message.GraphName;
        document.CloseAction = this.CloseAction;
        document.SelectedGraphType = message.SelectedGraphType;
        ActivateItem(document);
    }
}

public class ChartViewModel : Screen, IHandle<MeasurementRenamedEvent>
{
    private readonly IEventAggregator _Aggregator;
    private readonly ISupportServices _Services;

    public ChartViewModel(IEventAggregator aggregator, ISupportServices services) : base(aggregator, services)
    {
        if (aggregator == null)
            throw new ArgumentNullException("aggregator");
        _Aggregator = aggregator;
        _Aggregator.Subscribe(this);

        if (services == null)
            throw new ArgumentNullException("services");
        _Services = services;
    }}

当在MainViewModel中调用ActivateItem项方法时,CihldViewModel将添加到MainViewModel中的Items集合并激活子VM,然后您可以通过ChildViewModel中的this.Parent属性访问MainViewModel。