【问题标题】:How does a child ViewModel prompt the parent ViewModel to navigate away in Caliburn.Micro?子 ViewModel 如何提示父 ViewModel 在 Caliburn.Micro 中导航离开?
【发布时间】:2019-05-17 00:01:58
【问题描述】:

在 Caliburn.Micro 中,我有一个 Shell ViewModel,它有 3 个 IShell 属性,对应于关联视图中的 3 个内容控件。它们是“完整”、“列表”和“详细信息”。 'Full' 位于其他两个之上,与主窗体一样宽。 “列表”在左侧向下 1 行,“详细信息”与“列表”在同一行右侧 1 列。

当应用程序启动时,Login ViewModel 绑定到“Full”,而其他两个未绑定任何内容。该屏幕仅显示登录屏幕。用户应登录,完成后,“完整”内容控件应从显示登录视图模型切换到帐户视图模型。

为此,我需要 LoginViewModel 告诉 ShellViewModel(其父级)导航到 AccountViewModel。

我该怎么做?

public class ShellViewModel : Screen
{
    #region Fields

    private string _title = "License Manager";

    private Conductor<IScreen> _fullFrameConductor;
    private Conductor<IScreen> _listFrameConductor;
    private Conductor<IScreen> _detailFrameConductor;

    #endregion

    public ShellViewModel()
    {
        _fullFrameConductor = new Conductor<IScreen>();
        _listFrameConductor = new Conductor<IScreen>();
        _detailFrameConductor = new Conductor<IScreen>();

        FullFrame = Framework.GetContainer().Resolve<LoginViewModel>();            
    }

    #region Properties

    public string Title { get => _title; set => _title = value; }

    public IScreen FullFrame
    {
        get { return _fullFrameConductor.ActiveItem; }
        set {
            _fullFrameConductor.ActivateItem(value);
            NotifyOfPropertyChange(nameof(FullFrame));
        }
    }

    public IScreen ListFrame
    {
        get { return _listFrameConductor.ActiveItem; }
        set {
            _listFrameConductor.ActivateItem(value);
            NotifyOfPropertyChange(nameof(ListFrame));
        }
    }

    public IScreen DetailFrame
    {
        get { return _detailFrameConductor.ActiveItem; }
        set {
            _detailFrameConductor.ActivateItem(value);
            NotifyOfPropertyChange(nameof(DetailFrame));
        }
    }


    #endregion

    #region Commands

    public void ShowProducts()
    {
        ListFrame = Framework.GetContainer().Resolve<ProductListViewModel>();
        DetailFrame = Framework.GetContainer().Resolve<ProductViewModel>();
    }

    public void ShowLicenses()
    {
        ListFrame = Framework.GetContainer().Resolve<LicenseListViewModel>();
        DetailFrame = Framework.GetContainer().Resolve<LicenseViewModel>();
    }


    #endregion
}


public class LicenseViewModel : Screen
{

    public void Login()
    {
        // This should process the login and then tell the Shell it is done
        // then the shell should navigate to the Account ViewModel sharing
        // the user info with the AccountViewModel via a memory cache

        // How do I alert the screen ViewModel causing it to close this viewmodel
        // without causing a threading problem?
    }
}

【问题讨论】:

    标签: c# navigation caliburn.micro


    【解决方案1】:

    您可以利用事件聚合器在 LoginViewModel 和 ShellViewModel 之间进行通信。您可以在此处阅读有关事件聚合器的更多信息。

    首先,你需要创建一个消息类

    public class AuthenticationSuccessMessage
    {
        public bool IsValidLogin{get;set;}
    }
    

    那么下一步就是使用 EventAggregator 从 LicenseViewModel 通知 ShellViewModel。

    private IEventAggregator _eventAggregator;
     public LicenseViewModel (IEventAggregator eventAggregator) 
     {
        _eventAggregator = eventAggregator;
     }
    
     public void Login()
     {
        _eventAggregator.PublishOnUIThread(new AuthenticationSuccessMessage{IsValidLogin=true});
     }
    

    最后一步是订阅 ShellViewModel 中的事件。

    public class ShellViewModel:Screen, IHandle<AuthenticationSuccessMessage>
    {
       private readonly IEventAggregator _eventAggregator;
    
       public ShellViewModel:Screen(IEventAggregator eventAggregator) {
            _eventAggregator = eventAggregator;
            _eventAggregator.Subscribe(this);
        }
        void Handle<AuthenticationSuccessMessage>(AuthenticationSuccessMessage message)
        {
            if(message.IsValidLogin)
            {
                // Do Task
            }
        }
    }
    

    您可以阅读更多关于事件聚合器的信息here

    更新:别忘了订阅 ShellViewModel 中的 Event Aggregator。

    【讨论】:

    • 您需要订阅才能收到ShellViewModel中的消息。
    • @JackHughes 感谢您指出这一点。不知怎的,我错过了它。现已更新代码
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多