我需要在启动时在不同的窗口中一次显示两个WPF控件。父窗口属于同一类型,用户控件(和父窗口)在单独的程序集中定义,该程序集仅由主机项目引用。我使用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>();
用户控件作为窗口上下文提供给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;
}
我尝试了几种可能的解决方案,其中没有一种解决方案:
从Window1 viewmodel的构造函数中打开Window2(使用WindowManager.ShowWindow)。但是,这只打开了Window2,并且从未打开过Window1。反正可能不是个好主意..
在AppBootstrapper.OnStartup中创建一个窗口,使用App.xaml StartupUri创建另一个窗口,但这不允许我在通用父窗口中包含用户控件。我所能做的就是打开一个空的父窗口。
在接口上调用DisplayRootViewFor(),以便在启动时打开每个窗口。这样做的问题是无法设置窗口内容,因此您无法获得自定义父窗口,只有Caliburn.Micro提供的默认窗口。
答案 0 :(得分:1)
我是这样做的:
在AppBootstrapper.cs中,不是先调用DisplayRootViewFor,而是先创建父窗口的实例:
var parentWindow = _kernel.Get<IParentWindow>();
将用户控件提供给父窗口上下文:
parentWindow = _kernel.Get<IControl1>();
使用WindowManager.ShowWindow:
打开窗口_kernel.Get<IWindowManager>().ShowWindow(parentWindow, null, windowSettings);
只需重复第二个窗口的过程:
var window2 = _kernel.Get<IParentWindow>();
window2.WindowContent = _kernel.Get<IControl2>() ;
_kernel.Get<IWindowManager>().ShowWindow(window2, null, windowSettings);
这将在WPF中使用Caliburn.Micro创建两个窗口,其中包含在外部程序集中定义的用户控件。