将数据从屏幕传递到屏幕导体

时间:2016-04-07 20:00:58

标签: caliburn.micro

假设我的应用程序中有两个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中实现这一目标?

1 个答案:

答案 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");
}