您看不到任何内容的原因是您定义LayoutItem 模板的方式。这行不通。
还可以考虑使用自定义控件而不是 Frame。 Frame 很重。除非您不需要显示 HTML,否则请避免使用此控件。内容导航很容易实现,以防您想显示可导航的内容。只需将您的文档内容包装成UserControl。
您正在正确使用ActiveContent 属性。
要解决您的问题,您有三个推荐的解决方案,其中第一个不完全符合您的要求。既然你把DockingManager.LayoutItemTemplate定义错了,那我还是给大家看看吧。
解决方案1:本地LayoutItemTemplate
如果您只需要一个模板用于所有 LayoutDocument 和 LayoutAnchorable 容器,则可以使用 DockingManager.LayoutItemTemplate 属性。此属性接受单个 DataTemplate。 WPF 通常不支持嵌套的DataTemplate 定义,就像在您的代码中一样。
<ad:DockingManager>
<ad:DockingManager.LayoutItemTemplate>
<DataTemplate>
<Frame Source="Pages/SubclassAProject.xaml" />
</DataTemplate>
</ad:DockingManager.LayoutItemTemplate>
<ad:LayoutRoot>
<ad:LayoutPanel>
<ad:LayoutDocumentPaneGroup>
<ad:LayoutDocumentPane />
</ad:LayoutDocumentPaneGroup>
</ad:LayoutPanel>
</ad:LayoutRoot>
</ad:DockingManager>
解决方案 2:隐式 DataTemplate
在更高级的场景中,您会根据不同的模型显示不同的视图。如果显示的内容仅取决于模型的数据类型(如您的情况),推荐的方法是提供隐式 DataTemplate 定义。
WPF 将自动将隐式 DataTemplate 应用于与此模板的 DataTemplate.TargetType 匹配的每个数据类型。
DataTemplate 是隐式的,如果它没有明确分配 x:Key 值。为确保DataTemplate 实际上可以自动应用,DataTemplate 还必须在与目标类型相同的资源范围内定义。例如,在 App.xaml 的 Application.Resources 中定义 DataTemplate,将使模板在应用程序范围内自动应用。
<ad:DockingManager>
<ad:DockingManager.Resources>
<DataTemplate DataType="{x:Type vm:SubclassAViewModel}">
<Frame Source="Pages/SubclassAProject.xaml" />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:SubclassBViewModel}">
<Frame Source="Pages/SubclassBProject.xaml" />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:SubclassCViewModel}">
<Frame Source="Pages/SubclassCProject.xaml" />
</DataTemplate>
</ad:DockingManager.Resources>
<ad:LayoutRoot>
<ad:LayoutPanel>
<ad:LayoutDocumentPaneGroup>
<ad:LayoutDocumentPane>
</ad:LayoutDocumentPane>
</ad:LayoutDocumentPaneGroup>
</ad:LayoutPanel>
</ad:LayoutRoot>
</ad:DockingManager>
解决方案 3:DataTemplateSelector
之前使用隐式DataTemplate 定义的解决方案可以替换为DataTemplateSelector。 DataTemplateSelector 是另一个 WPF 概念,可以选择性地应用 DataTemplate。
DataTemplateSelector 是推荐的选择,如果选择 DataTemplate 可能取决于比模型的数据类型更复杂的约束条件。它允许例如评估数据项并根据某些标准选择适当的模板。
要定义一个模板选择器,你必须扩展DataTemplateSelector,它应该返回一个DataTemplate。
最简单的方法是使用x:Key 在App.xaml 资源字典中定义模板,然后根据条件从它们中进行选择。
DockingManger 通过分配@ 来接受模板选择器987654357@财产:
App.xaml
使用x:Key 定义显式DataTemplate:
<Application.Resources>
<DataTemplate x:Key="SubclassAViewModelTemplate" DataType="{x:Type vm:SubclassAViewModel}">
<Frame Source="Pages/SubclassAProject.xaml" />
</DataTemplate>
<DataTemplate x:Key="SubclassBViewModelTemplate" DataType="{x:Type vm:SubclassBViewModel}">
<Frame Source="Pages/SubclassBProject.xaml" />
</DataTemplate>
<DataTemplate x:Key="SubclassCViewModelTemplate" DataType="{x:Type vm:SubclassCViewModel}">
<Frame Source="Pages/SubclassCProject.xaml" />
</DataTemplate>
</Application.Resources>
DocumentManagerTemplateSelector.cs
以下代码使用自 C# 8.0 起可用的 Switch 表达式。它可以用 switch 语句或级联 if 语句替换。
class DocumentManagerTemplateSelector : DataTemplateSelector
{
#region Overrides of DataTemplateSelector
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
return item switch
{
SubclassAViewModel _ => Application.Current.Resources["SubclassAViewModelTemplate"] as DataTemplate,
SubclassBViewModel _ => Application.Current.Resources["SubclassBViewModelTemplate"] as DataTemplate,
SubclassCViewModel _ => Application.Current.Resources["SubclassCViewModelTemplate"] as DataTemplate,
_ => base.SelectTemplate(item, container)
};
}
#endregion
}
MainWindow.xaml
<ad:DockingManager>
<xcad:DockingManager.LayoutItemTemplateSelector>
<local:DocumentManagerTemplateSelector />
</xcad:DockingManager.LayoutItemTemplateSelector>
<ad:LayoutRoot>
<ad:LayoutPanel>
<ad:LayoutDocumentPaneGroup>
<ad:LayoutDocumentPane>
</ad:LayoutDocumentPane>
</ad:LayoutDocumentPaneGroup>
</ad:LayoutPanel>
</ad:LayoutRoot>
</ad:DockingManager>