在 Caliburn Micro 中执行多个 windows 的正确方法?
Correct way to conduct multiple windows in Caliburn Micro?
我正在使用 Caliburn.Micro 开发应用程序。我需要同时在多台显示器上打开一组相同的 windows,但我不知道如何干净利落地做到这一点。
我的想法是这样的:
ChildViewModel
/ ChildView
包含我需要在多个屏幕上显示的内容。
ParentViewModel
继承自 ConductorBase<ChildViewModel>
.
- 创建
ParentViewModel
时,它会创建所需数量的 ChildViewModel
并使用 WindowManager.ShowWindow
来显示它们中的每一个。
- 我的
WindowManager
实现负责将这些视图放置在它们应该在的位置。
以上所有工作,有一个例外: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 对用户可见,而是将这些命令转发给 MultipleDesktopManager。
MultipleDesktopManager 不可见且不是 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)。这相当于此架构中的 MultipleDesktopManager。
关于仅从系统托盘启动的 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" 的有趣信息。最后,MultipleDesktopManager 的想法基本上是管理许多 windows 的简单导体的想法,无需实现 IConductor 接口但仍然使用 WindowManager 以便正确处理 SingleDesktopVMs 生命周期。
我正在使用 Caliburn.Micro 开发应用程序。我需要同时在多台显示器上打开一组相同的 windows,但我不知道如何干净利落地做到这一点。
我的想法是这样的:
ChildViewModel
/ChildView
包含我需要在多个屏幕上显示的内容。ParentViewModel
继承自ConductorBase<ChildViewModel>
.- 创建
ParentViewModel
时,它会创建所需数量的ChildViewModel
并使用WindowManager.ShowWindow
来显示它们中的每一个。 - 我的
WindowManager
实现负责将这些视图放置在它们应该在的位置。
以上所有工作,有一个例外: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 对用户可见,而是将这些命令转发给 MultipleDesktopManager。
MultipleDesktopManager 不可见且不是 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)。这相当于此架构中的 MultipleDesktopManager。
关于仅从系统托盘启动的 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" 的有趣信息。最后,MultipleDesktopManager 的想法基本上是管理许多 windows 的简单导体的想法,无需实现 IConductor 接口但仍然使用 WindowManager 以便正确处理 SingleDesktopVMs 生命周期。