在 Caliburn Micro 中执行多个 windows 的正确方法?

Correct way to conduct multiple windows in Caliburn Micro?

我正在使用 Caliburn.Micro 开发应用程序。我需要同时在多台显示器上打开一组相同的 windows,但我不知道如何干净利落地做到这一点。

我的想法是这样的:

以上所有工作,有一个例外:ParentView 显示在它自己的 window 中。我怎样才能避免这种情况发生?做我想做的事情的规范方式是什么?

我想做的是从单个导体传导多个 windows,而不是导体本身显示 window。

可能我又漏掉了什么,不过你可以根据你提供的信息做下面的事情

第 1 步

  • 转到处理您的 Menuclick 的 class(VM)
  • 添加一个私有值ParentConductor,它会像你的ParentViewModel做同样的事情(持有每个Child的引用,如果一个被关闭则关闭所有)

第 2 步

  • 修改您的 MenuclickClickCommand 以便您每次单击它都会发生
  • 整合你的ParentConductor
  • 创建您的 Child 并将 ref 添加到您的 ParentConductor
  • 使用 Caliburn 创建 windows foreach child

现在您应该可以关闭所有 Child(如果一个已关闭)。 没有必要创建一个 ParentView 因为你的指挥会和你的 class(VM) 一样长寿。

您还可以添加一种方法,以便售票员在关闭 Child 的

后可以从 class 中删除自己

这个架构怎么样?

                          SystemTrayVM
      (VM for your notification area, its View is the sys tray icon)
                                |
                                |
                      MultipleDesktopManager
      (not a VM, not a ConductorBase, no View, not visible)
                                |
            .-------------------|------------------.
            |                   |                  |
            |                   |                  |
    SingleDesktopVM      SingleDesktopVM     SingleDesktopVM
(its View holds child views. If necessary, it can be a ConductorBase)
                                |
                  .-------------|------------.------ - - - .
                  |             |            |
                  |             |            |
         SideBarChildVM    MainChildVM   FooterChildVM
  • SystemTrayVM 负责通过通知区域提供的所有交互(右键单击菜单操作等)。它实际上不会 open/close 和 windows 对用户可见,而是将这些命令转发给 Mu​​ltipleDesktopManager

  • Mu​​ltipleDesktopManager 不可见且不是 VM。它的责任是例如open/close 所有单个桌面 parent windows 需要时。完全独立 windows,应该不需要完全熔断的导体。根据我的经验,为它提供一个 IWindowManager 就足够了,这样它实际上就可以 show/close 单个桌面 parent windows。也许它也可以 activate/deactivate 它们,但不需要跟踪 当前 活动项目或类似的东西。

  • SingleDesktopVM 负责其内部显示的所有 child views/VMs。因此,如果需要,这可能是一个指挥......这实际上取决于 parent 中那些 child 视图的生命周期。例如。如果有一个 command-bar 和一个主要内容并且它们始终存在,那么您可能可以使用包含其他 VM 的更简单的 parent VM。

最近我们遇到并解决了 WPF 应用程序开始时不可见的问题,只能在系统托盘中找到,并且从那里能够 show/hide 实际 主应用程序 window.
在那种情况下,我们将 hiding/showing 主应用程序 window 的任务卸载到由 SystemTrayVM 调用的助手 class(不是 VM)。这相当于此架构中的 Mu​​ltipleDesktopManager

关于仅从系统托盘启动的 WPF 应用程序,我们将 PoC on GitHub that shows how to completely integrate this WPF NotifyIcon 控件与 Caliburn.Micro ViewModel-first 方法放在一起,并通过 Autofac 进行 DI。

编辑:理由是 CM 提供的现成的 Conductor 实现似乎更适合 window 持有其他 child windows。如果持有人本身不可见,那么这些导体实施可能不是完美的选择。正如您在评论中所说,这就像需要一个导体 而不是 也是一个屏幕。 CM composition doc page 上有一个关于 "Quasi-Conductors" 的有趣信息。最后,Mu​​ltipleDesktopManager 的想法基本上是管理许多 windows 的简单导体的想法,无需实现 IConductor 接口但仍然使用 WindowManager 以便正确处理 SingleDesktopVMs 生命周期。