假设我的应用程序中有两个ViewModel和一个Screen Conductor。
public class ShellViewModel : Conductor<IScreen>, IShell
{
public ShellViewModel()
{
ShowConnectionScreen();
}
public void ShowConnectionScreen()
{
ActivateItem(new ConnectionViewModel());
}
public void ShowSetupScreen()
{
ActivateItem(new SetupViewModel());
}
}
第一个ViewModel在启动时显示,包含一些设置信息和一个Connect
按钮,用于初始化到某个地方的连接。
如果连接成功建立,那么我希望第一个ViewModel关闭,第二个ViewModel显示一些有关连接的信息。如果失败,第一个ViewModel应该只显示它,并允许用户再次尝试连接。
因此,我需要将实际的连接对象从第一个ViewModel传递到第二个ViewModel和Screen Conductor,以便在成功时更改视图模型。
如何在Caliburn.Micro中实现这一目标?
答案 0 :(得分:0)
说明@mvermef的评论:
在3个类对象之间使用通用类型,显然会创建这个类型的问题
这将是第一个视图模型填充并由第二个视图模型使用的connection
对象。
public class Connection {
// props, methods, etc...
}
并在构造函数中传递它或使其成为所有3个类的属性
public class ShellViewModel : Conductor<IScreen>, IShell
{
public Connection Connection { get; set; }
public ShellViewModel()
{
Connection = new Connection();
ShowConnectionScreen();
}
public void ShowConnectionScreen()
{
ActivateItem(new ConnectionViewModel(Connection));
}
public void ShowSetupScreen()
{
ActivateItem(new SetupViewModel(Connection));
}
}
使用ConnectionViewModel中的Connection对象执行您想要的操作
public class ConnectionViewModel : Screen
{
public Connection Connection { get; set; }
// establish connection
// can call (Parent as IConductor).DeactivateItem(this)
// after connection is established
}
如果通过(1)通过ConnectionViewModel的Deactivated事件注册(假设您是子类屏幕)注册,则可以通知父指挥。或者(2)如果连接已建立且ShellViewModel实现IHandle,则可以使用EventAggregator触发事件。然后,您可以在Deactivated事件处理程序或Handle方法中调用ShowSetupScreen()。
选项1:
// ShellViewModel
public void ShowConnectionScreen()
{
var connectionVM = new ConnectionViewModel();
connectionVM.Deactivated += ConnectionViewModel_Deactivated;
ActivateItem();
}
private void Scheduler_Deactivated1(object sender, DeactivationEventArgs e)
{
ShowSetupScreen();
}
选项2:
public class ShellViewModel : Conductor<IScreen>,
IShell, IHandle<string>
{
private readonly IEventAggregator _eventAggregator;
public ShellViewModel(IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator;
_eventAggregator.Subscribe(this);
}
// from IHandle<string>. you can create a custom object to represent this event
public void Handle(string message)
{
if (message.Equals("connection.successful"))
{
ShowSetupScreen();
}
}
}
public class ConnectionViewModel : Screen
{
private readonly IEventAggregator _eventAggregator;
public ConnectionViewModel(IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator;
}
// call _eventAggregator.PublishOnUIThread("connection.successful");
}