在Caliburn Micro中进行多个窗口操作的正确方法

本文关键字:操作 窗口 方法 Micro Caliburn | 更新日期: 2023-09-27 18:06:33

我正在使用Caliburn.Micro.开发一个应用程序。我需要在多个监视器上同时打开一组相同的窗口,但我不知道如何干净地做到这一点。

我的想法是:

  • ChildViewModel/ChildView包含我需要在多个屏幕上显示的内容
  • 继承自CCD_ 4的CCD_
  • 创建ParentViewModel时,它会创建所需数量的ChildViewModel,并使用WindowManager.ShowWindow来显示它们中的每一个
  • 我的WindowManager实现负责将这些视图放置在它们应该位于的位置

以上所有操作都有效,只有一个例外:ParentView显示在自己的窗口中。我该如何避免这种情况发生?做我想做的事情的典型方式是什么?

我想做的是从一个导体传导多个窗口,而导体本身不显示窗口。

在Caliburn Micro中进行多个窗口操作的正确方法

这个模式怎么样?

                          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负责通过通知区域提供的所有交互(右键单击菜单操作等(。它实际上不会打开/关闭用户可见的窗口,而是将这些命令转发到MultipleDesktopManager

  • MultipleDesktopManager不可见,并且不是虚拟机。其职责是在需要时打开/关闭所有单桌面父窗口。作为完全独立的窗户,不需要完全熔断的导线。根据我的经验,为它提供IWindowManager就足够了,这样它就可以实际显示/关闭单个桌面父窗口。也许它也可以激活/停用它们,但不需要跟踪当前活动项目或类似的东西。

  • SingleDesktopVM负责其内部显示的所有子视图/VM。如果需要的话,这可能是一名指挥家。。。这实际上取决于父视图中那些子视图的生命周期。例如,如果有一个命令栏和一个主内容,并且它们总是在那里,那么您可能可以使用包含其他虚拟机的更简单的父虚拟机

在最近的一段时间里,我们面临着&解决了WPF应用程序启动时不可见、只能在系统托盘中找到的问题,并且从那里可以显示/隐藏实际的主应用程序窗口
在该场景中,我们将隐藏/显示主应用程序窗口的任务卸载到SystemTrayVM调用的助手类(而不是VM(。这相当于此模式中的MultipleDesktopManager

关于仅从系统托盘开始的WPF应用程序,我们在GitHub上制作了一个PoC,展示了如何将WPF NotifyIcon控件与Caliburn.Micro ViewModel优先方法和通过Autofac的DI完全集成。

编辑:基本原理是CM提供的现成Conductor实现似乎更适合窗口容纳其他子窗口。如果支架本身不可见,那么这些导体实现可能不是完美的选择。正如您在评论中所说,这就像需要一个而不是同时也是一个屏幕。CM作文文档页面上有一个关于"准导体"的有趣部分。最后,MultipleDesktopManager的想法基本上是一个管理多个窗口的简单导体,不需要实现ICconductor接口,但仍然使用WindowManager来正确处理SingleDesktopVMs生命周期。

也许我又错过了什么,但你可以根据你提供的信息进行以下

步骤1。

  • 转到处理Menuclick的类(VM(
  • 添加一个私有值ParentConductor,它将执行与ParentViewModel相同的操作(为每个Child保留一个ref,如果其中一个已关闭则关闭所有(

步骤2。

  • 修改菜单clickClickCommand,以便每次单击它时都会发生以下情况
  • 输入您的ParentConductor
  • 创建您孩子的并将ref添加到您的ParentConductor
  • 使用Caliburn为每个孩子创建窗口

现在,如果关闭了所有Child的,您应该能够关闭其中一个。没有必要创建CCD_ 14,因为您的导体的寿命与您的类(VM(的寿命一样长。

您还可以添加一个方法,以便指挥能够在关闭其Child的后将其自身从类中删除