在Caliburn.Micro中,我有一个Shell ViewModel,它具有3个IShell属性,分别对应于关联的View中的3个内容控件。它们是“完整”,“列表”和“详细信息”。 “ Full”位于其他两个上方,并且与宿主Form一样宽。 “列表”位于左侧第一行,而“详细信息”与右侧“列表” 1列在同一行。
应用程序启动时,Login ViewModel绑定到“ Full”,其他两个都没有绑定。屏幕仅显示登录屏幕。用户应登录,完成后,“完整”内容控件应从显示登录ViewModel切换到AccountViewModel。
为此,我需要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?
}
}
答案 0 :(得分:0)
您可以利用Event Aggregator在LoginViewModel和ShellViewModel之间进行通信。您可以在此处阅读有关Event Aggregator的更多信息。
首先,您需要创建一个消息类
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。