【问题标题】:Passing data from screen to screen conductor将数据从屏幕传递到屏幕导体
【发布时间】:2016-04-07 20:00:57
【问题描述】:

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

【问题讨论】:

  • 在 3 个类对象之间使用公共类型,显然创建有问题的这种类型并将其传递给构造函数或使其成为所有 3 个类的属性...?或者,您可以使用 EventAggregator 发布其他 ViewModel 将接受和处理或忽略的事件。

标签: caliburn.micro


【解决方案1】:

为了说明@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 事件(假设您是 Screen 的子类)注册来通知父导体是否建立了连接。或者 (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");
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-16
    • 1970-01-01
    • 2021-03-30
    • 1970-01-01
    • 2020-06-14
    • 2020-11-08
    • 1970-01-01
    • 2021-01-06
    相关资源
    最近更新 更多