使用 Caliburn.Micro 同时显示两个 WPF windows
Display two WPF windows simultaneously using Caliburn.Micro
我需要在启动时分别 windows 同时显示两个 WPF 控件。父级 windows 属于同一类型,用户控件(和父级 window)在单独的程序集中定义,仅由宿主项目引用。我使用 Caliburn.Micro 作为 MVVM 框架,Ninject 作为 IoC。如何做到这一点?
所有视图模型都派生自 PropertyChangedBase。我已经设置了 AppBootstrapper 来定义 Caliburn.Micro 标准绑定,例如 WindowManager:
_kernel.Bind<IControl1>().To<Control1ViewModel>().InSingletonScope();
_kernel.Bind<IControl2>().To<Control2ViewModel>().InSingletonScope();
_kernel.Bind<IParentWindow>().To<ParentWindowViewModel>();
并为创建 Control1 的 OnStartup 创建了覆盖:
DisplayRootViewFor<IWindow1>();
用户控件作为 window 上下文提供给 ContentControl 中的父 window,如下所示:
<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;
}
我尝试了几种可能的解决方案,none 其中有效:
从 Window1 视图模型的构造函数中打开 Window2(使用 WindowManager.ShowWindow)。但是,这只打开了 Window2,并没有打开 Window1。无论如何可能不是一个好主意..
在 AppBootstrapper.OnStartup 中创建一个 window,并使用 App.xaml StartupUri 创建另一个 window,但是这不允许我包含用户在通用父级 window 中进行控制。我所能做的就是打开一个空的父 window.
在界面上调用 DisplayRootViewFor() 为每个 window 在启动时打开。这样做的问题是无法设置 window 内容,因此您得不到自定义父级 window,只有 Caliburn.Micro 提供的默认 window。
我是这样做的:
在AppBootstrapper.cs中,不是调用DisplayRootViewFor,而是首先创建父window的一个实例:
var parentWindow = _kernel.Get<IParentWindow>();
将用户控件提供给父 window 上下文:
parentWindow = _kernel.Get<IControl1>();
用WindowManager.ShowWindow打开window:
_kernel.Get<IWindowManager>().ShowWindow(parentWindow, null, windowSettings);
简单地重复第二个过程window:
var window2 = _kernel.Get<IParentWindow>();
window2.WindowContent = _kernel.Get<IControl2>() ;
_kernel.Get<IWindowManager>().ShowWindow(window2, null, windowSettings);
这将创建两个 windows,包含在外部程序集中定义的用户控件,使用 WPF 中的 Caliburn.Micro。
我需要在启动时分别 windows 同时显示两个 WPF 控件。父级 windows 属于同一类型,用户控件(和父级 window)在单独的程序集中定义,仅由宿主项目引用。我使用 Caliburn.Micro 作为 MVVM 框架,Ninject 作为 IoC。如何做到这一点?
所有视图模型都派生自 PropertyChangedBase。我已经设置了 AppBootstrapper 来定义 Caliburn.Micro 标准绑定,例如 WindowManager:
_kernel.Bind<IControl1>().To<Control1ViewModel>().InSingletonScope();
_kernel.Bind<IControl2>().To<Control2ViewModel>().InSingletonScope();
_kernel.Bind<IParentWindow>().To<ParentWindowViewModel>();
并为创建 Control1 的 OnStartup 创建了覆盖:
DisplayRootViewFor<IWindow1>();
用户控件作为 window 上下文提供给 ContentControl 中的父 window,如下所示:
<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;
}
我尝试了几种可能的解决方案,none 其中有效:
从 Window1 视图模型的构造函数中打开 Window2(使用 WindowManager.ShowWindow)。但是,这只打开了 Window2,并没有打开 Window1。无论如何可能不是一个好主意..
在 AppBootstrapper.OnStartup 中创建一个 window,并使用 App.xaml StartupUri 创建另一个 window,但是这不允许我包含用户在通用父级 window 中进行控制。我所能做的就是打开一个空的父 window.
在界面上调用 DisplayRootViewFor() 为每个 window 在启动时打开。这样做的问题是无法设置 window 内容,因此您得不到自定义父级 window,只有 Caliburn.Micro 提供的默认 window。
我是这样做的:
在AppBootstrapper.cs中,不是调用DisplayRootViewFor,而是首先创建父window的一个实例:
var parentWindow = _kernel.Get<IParentWindow>();
将用户控件提供给父 window 上下文:
parentWindow = _kernel.Get<IControl1>();
用WindowManager.ShowWindow打开window:
_kernel.Get<IWindowManager>().ShowWindow(parentWindow, null, windowSettings);
简单地重复第二个过程window:
var window2 = _kernel.Get<IParentWindow>();
window2.WindowContent = _kernel.Get<IControl2>() ;
_kernel.Get<IWindowManager>().ShowWindow(window2, null, windowSettings);
这将创建两个 windows,包含在外部程序集中定义的用户控件,使用 WPF 中的 Caliburn.Micro。