使用Caliburn.Micro同时显示两个WPF窗口

本文关键字:两个 WPF 窗口 Micro Caliburn 显示 使用 | 更新日期: 2023-09-27 18:15:30

我需要在启动时在不同的窗口中同时显示两个WPF控件。父窗口具有相同的类型,并且用户控件(和父窗口)在单独的程序集中定义,该程序集仅由主机项目引用。我用的是Caliburn。Micro作为MVVM框架,Ninject用于IoC。如何做到这一点?

所有视图模型都是从PropertyChangedBase派生的。我已经设置了AppBootstrapper来定义Caliburn。微标准绑定,如WindowManager:

  _kernel.Bind<IControl1>().To<Control1ViewModel>().InSingletonScope();
  _kernel.Bind<IControl2>().To<Control2ViewModel>().InSingletonScope();
  _kernel.Bind<IParentWindow>().To<ParentWindowViewModel>();

并为OnStartup创建了一个覆盖,该覆盖创建了Control1:

DisplayRootViewFor<IWindow1>();

用户控件作为窗口上下文提供给ContentControl中的父窗口,如下所示:

<ContentControl x:Name="WindowView"
     HorizontalAlignment="Stretch"
     VerticalAlignment="Stretch"
     cal:View.Context="{Binding ViewContext}"
     cal:View.Model="{Binding WindowContent}" />

最后,我还提供了对SelectAssemblies的重写,以便Caliburn。Micro可以在dll中找到视图和视图模型:

protected override IEnumerable<Assembly> SelectAssemblies()
{
    var assemblies = base.SelectAssemblies().ToList();
    assemblies.Add(typeof(IControl1).GetTypeInfo().Assembly);
    return assemblies;
}

我尝试了几种可能的解决方案,但都不起作用:

  1. 从Window1视图模型的构造函数中打开Window2(使用WindowManager.ShowWindow)。然而,这只能打开Window2,而不能打开Window1。可能不是个好主意…

  2. 在AppBootstrapper中创建一个窗口。OnStartup和使用App.xaml StartupUri的另一个窗口,但是这不允许我在通用父窗口中包含用户控件。我只能打开一个空的父窗口。

  3. 调用DisplayRootViewFor()在每个窗口启动时打开的接口。这样做的问题是没有办法设置窗口内容,所以你不会得到自定义父窗口,只是由Caliburn.Micro提供的默认窗口。

使用Caliburn.Micro同时显示两个WPF窗口

我的做法如下:

在AppBootstrapper.cs中,不是调用DisplayRootViewFor,而是先创建一个父窗口的实例:

var parentWindow = _kernel.Get<IParentWindow>();

为父窗口上下文提供用户控制:

parentWindow = _kernel.Get<IControl1>();

使用WindowManager打开窗口。显示窗口:

_kernel.Get<IWindowManager>().ShowWindow(parentWindow, null, windowSettings);

对第二个窗口重复此过程:

var window2 = _kernel.Get<IParentWindow>();
window2.WindowContent = _kernel.Get<IControl2>() ;
_kernel.Get<IWindowManager>().ShowWindow(window2, null, windowSettings);

这将使用Caliburn创建两个窗口,其中包含在外部程序集中定义的用户控件。微在WPF。