Jon*_*Jon 33
创建多个shell是正确的想法.您只需要适当地处理细节.
当然,Prism的方法是DelegateCommand处理新shell的创建.考虑到这个命令并不严格属于任何特定的ViewModel(我说它有一个应用程序范围),对于我来说,拥有public static class ApplicationWideCommands一个CreateNewShellCommand静态属性感觉更好.然后,您可以根据需要从XAML绑定到它{x:Static}或从代码隐藏执行它.
这个命令需要处理两件事:
Window(实际上,a Shell)IRegionManager为新shell 实例化一个新的,以便现有shell中的区域与新shell中的区域之间的区域名称不会发生冲突IRegionManager我将从头到尾解决这个问题,因为它更容易解释.
在Prism中声明区域时,除了区域名称之外,您还可以声明要使用的区域管理器.通常您不需要这样做,但在这里我们需要选择RegionManager使用哪个,因为区域名称在单个区域管理器的范围内必须是唯一的.由于区域名称在视图的XAML中是硬编码的,并且以另一种方式分配它们将是一个主要的痛苦,我们需要更改方程的另一半:每个shell使用的区域管理器实例.所以里面Shell.xaml可能会有这样的事情:
<ContentControl
regions:RegionManager.RegionManager="{Binding RegionManager}"
regions:RegionManager.RegionName="ExampleRegion"
/>
Run Code Online (Sandbox Code Playgroud)
这将指示它属于IRegionManager绑定提供的每个shell中的"WorkspaceRegion" .由于shell通常没有DataContext,我们可以RegionManager在shell类本身声明属性:
public partial class Shell : Window
{
public Shell(IRegionManager regionManager)
{
this.RegionManager = regionManager;
InitializeComponent();
}
public IRegionManager RegionManager { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)
所以现在我们只需要确保每个Shell实例都有自己的实例RegionManager.对于"第一个"shell,这将由BootStrapper.(下面的代码使用DI容器来解析对象,并且示例使用UnityContainer.如果使用MEF进行依赖注入,只需在心理上转换为等效代码.)
protected override DependencyObject CreateShell()
{
// I am assuming you have a reference to the DI container
var regionManager = this.Container.Resolve<IRegionManager>();
return new Shell(regionManager);
}
Run Code Online (Sandbox Code Playgroud)
对于其他shell,它将通过以下方式完成CreateNewShellCommand:
private static ExecuteCreateNewShellCommand()
{
// I am assuming you have a reference to the DI container
var regionManager = this.Container.Resolve<IRegionManager>();
ver newRegionManager = regionManager.CreateRegionManager();
var shell = new Shell(newRegionManager);
// The rest is easy, for example:
shell.Show();
}
Run Code Online (Sandbox Code Playgroud)
这里有一个重要的警告:它RegionManager作为单身人士注册到容器中.这意味着无论何时解决,IRegionManager 您都将获得相同的实例.出于这个原因,我们通过调用IRegionManager.CreateRegionManager方法创建一个新实例(这适用于Prism v4;我不确定v2).
此时,您知道如何创建任意数量的新Shell实例并相应地连接区域.
您需要注意的最后一个细节是,每个shell中托管的所有区域,无论其可视树有多深,都必须绑定到相同的区域RegionManager.
这意味着您必须像ContentControl上面的示例中那样显式设置区域管理器,以用于应用程序中所有视图中的所有区域.幸运的是,这很容易完成,因为:
Shell可视树中a的后代Shell已经公开正确RegionManager的属性,所以我们可以绑定到你会这样做:
<ItemsControl
regions:RegionManager.RegionManager="{Binding RegionManager, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Shell}}}"
regions:RegionManager.RegionName="AnotherRegion"
/>
Run Code Online (Sandbox Code Playgroud)
你现在应该准备好了.
| 归档时间: |
|
| 查看次数: |
9967 次 |
| 最近记录: |