问题描述
我偶然发现了一个问题,我在 CM 的官方文档中没有找到解决方案。 我们的应用程序看起来与此图像相似:
在搜索 StackOverflow 时,我找到了使用 Conductor<object>.Collection.AllActive
类 (more active screens / views in shell caliburn micro or another MVVM framework) 执行类似操作的解决方案。我遇到的最大问题是,我找不到使用工厂进行依赖注入的方法。 Shellviewmodel
的构造函数目前看起来像这样。
public Shellviewmodel(
Func<Footerviewmodel> footerviewmodelFactory,Func<Loginviewmodel> loginviewmodelFactory)
{
this.ActivateItemAsync(loginviewmodelFactory);
this.ActivateItemAsync(footerviewmodelFactory);
}
显然这是行不通的,因为ContentControl不能显示工厂,需要一个Screen。但是我如何首先设法将对象绑定到外壳,同时仍然保持依赖注入的特性?否则,一个简单的解决方法就是为 viewmodel 创建一个新实例并传递所有参数,这在我看来简直太脏了。
解决方法
我终于明白了。虽然我讨厌 Java 中的工厂模式,但它在 Caliburn Micro 中似乎是必要的并且是有道理的。
无论如何,我创建了一个类似这样的工厂:
public class FooterFactory
{
// Add all the needed interfaces you get injected from the IoC container here.
private readonly IMyInterface myImplementation;
public FooterFactory(IMyInterface myImplementation,...)
{
this.myImplementation = myImplementation;
}
//Creates the ViewModel. You can also pass some parameters here.
public FooterViewModel Create(...)
{
return new FooterViewModel (...,this.myImplementation);
}
}
在工厂被添加到引导程序后,它可以很容易地添加,如下所示。不过,我的最初方法有一些问题。因此,我稍微更改了代码。
public ShellViewModel(
FooterFactory footerFactory,Func<LoginViewModel> loginViewModelFactory)
{
this.ActivateItemAsync(loginViewModelFactory);
this.FooterViewModel = footerFactory.Create(...);
}
我的 XAML 看起来像这样。
<Window x:Class="My.Client.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
WindowState="Maximized"
WindowStartupLocation="CenterScreen"
Title="Dummy" Icon="/Resources/favicon.ico">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="120" />
</Grid.RowDefinitions>
<ContentControl Name="ActiveItem" Grid.Row="0"/>
<ContentControl Name="FooterViewModel" Grid.Row="1" />
</Grid>
</Window>
注意:正如我所说,这是我使用的代码的简化版本。无论如何,它应该强调如何解决这个问题的方法。这种方法的好处是,您不需要带有多个项目控件的 Conductor<>.Collection
。因此,您无需弄乱对象的顺序,例如,如果一个对象的加载时间比另一个对象长,或者您必须停用某些对象。 + 如果您想在屏幕上显示更多内容(例如标题、菜单栏等),您可以在 XAML 中创建多个 ContentControl
。