Caliburn.Micro屏幕通过导体过渡

时间:2012-11-28 16:21:50

标签: c# .net xaml mvvm caliburn.micro

我有指挥 呈现的 Caliburn.Micro 外壳(即空 XAML 视图以包含其他视图)视图模型。从那里我通过

打开屏幕
ActivateItem(...)

通常从新显示的对话框中,用户可以执行某些操作并单击按钮(确定取消构建 ....)每个应该转换到另一个屏幕(在shell中)。

public MyDialog : Screen
{
    public void Ok()
    {
        // TODO: Somehow tell the conductor or called of this class about this action.
    }
}

有哪些好方法可以实现这种对话操作/消息屏幕转换?

  • 简单的 .NET事件是可能的 - 这不是一个坏主意吗?
  • CM IEventAggregator 也可以通过更改视图来实现
  • 一旦通过TryClose()关闭了ViewModel 结果结果来检查来自导体的导体 - 应该是可能的,只是不知道如何在CM中实现这一点。
  • 从该屏幕引用shell Conductor实例(通过IoC或直接) - 这似乎是强耦合。

你能告诉我吗。

1 个答案:

答案 0 :(得分:3)

我首选的方法是使用EventAggregator来促进VM之间的消息传递。

当您有多个窗口正在侦听某种类型的事件时(例如,可能显示上下文敏感属性的具有多个工具窗口的Visual Studio样式界面),这尤其有用,但是对于此实现来说听起来有点过分。当然,优点仍然是虚拟机之间的松散耦合和缺少事件(这是一件好事!)

听起来你想要一个模态对话框弹出并显示一个选项,然后在第一个屏幕返回后激活另一个屏幕。

您可以将事件处理程序附加到子VM中的Deactivated事件,该事件将在项目停用时触发。它还在参数中传递一个布尔值,以通知是否关闭了已停用的项目 - 您可以检查并激活指挥中的相应屏幕。

e.g。

this.Deactivated += new EventHandler<DeactivationEventArgs>(WorkspaceViewModel_Deactivated);

void WorkspaceViewModel_Deactivated(object sender, DeactivationEventArgs e)
{
    if(e.WasClosed) // raise some event
}

然后将一个事件传递给指挥,我不会真的去事件路线。这会将VM单向耦合,因此它可能不是最灵活的解决方案

另一种方法是通过事件聚合器触发消息,告诉指挥在子VM关闭时需要打开一个不同的窗口。可以使用相同的方法,但它是解耦的

this.Deactivated += new EventHandler<DeactivationEventArgs>(WorkspaceViewModel_Deactivated);

void WorkspaceViewModel_Deactivated(object sender, DeactivationEventArgs e)
{
    if(e.WasClosed) MainConductor.EventAggregator.Publish(new ActivateWindowMessage(typeof(SomeVM));
}