2

我有一个由Conductor ViewModel呈现的Caliburn.Micro shell(即包含其他视图的空XAML视图)。从那里我通过以下方式打开一个屏幕

ActivateItem(...)

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

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

实现这种对话动作/消息屏幕转换的好方法是什么?

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

您能否提一些建议。

4

1 回答 1

3

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

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

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

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

例如

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

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

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

另一种方法是通过事件聚合器触发一条消息,告诉指挥者它需要在子 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));
}
于 2012-11-28T18:18:41.577 回答