在Caliburn Micro中进行多个窗口操作的正确方法
本文关键字:操作 窗口 方法 Micro Caliburn | 更新日期: 2023-09-27 18:06:33
我正在使用Caliburn.Micro.开发一个应用程序。我需要在多个监视器上同时打开一组相同的窗口,但我不知道如何干净地做到这一点。
我的想法是:
ChildViewModel
/ChildView
包含我需要在多个屏幕上显示的内容- 继承自CCD_ 4的CCD_
- 创建
ParentViewModel
时,它会创建所需数量的ChildViewModel
,并使用WindowManager.ShowWindow
来显示它们中的每一个 - 我的
WindowManager
实现负责将这些视图放置在它们应该位于的位置
以上所有操作都有效,只有一个例外:ParentView
显示在自己的窗口中。我该如何避免这种情况发生?做我想做的事情的典型方式是什么?
我想做的是从一个导体传导多个窗口,而导体本身不显示窗口。
这个模式怎么样?
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的后将其自身从类中删除