Причина, по которой вы не можете видеть какой-либо контент, заключается в том, как вы определили свои LayoutItem
шаблоны. Это не сработает.
Также рассмотрите возможность использования пользовательского элемента управления вместо Frame
. Frame
очень тяжелый. Если вам не нужно отображать HTML, избегайте этого элемента управления. Навигацию по содержимому очень легко реализовать, если вы хотите показать содержимое, по которому можно перемещаться. Просто оберните содержимое документа в файл UserControl
.
Вы правильно используете свойство ActiveContent
.
Чтобы решить вашу проблему, у вас есть три рекомендуемых решения, первое из которых не совсем соответствует вашим требованиям. Поскольку вы определили DockingManager.LayoutItemTemplate
неправильно, я все равно покажу это.
Решение 1. Локальный LayoutItemTemplate
Если вам нужен только один шаблон для всех контейнеров LayoutDocument
и LayoutAnchorable
, вы можете использовать свойство DockingManager.LayoutItemTemplate
. Это свойство принимает один DataTemplate
. Вложенные определения DataTemplate
, как и в вашем коде, обычно не поддерживаются WPF.
<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
также должен быть определен в той же области ресурсов, что и целевой тип. Например, определение DataTemplate
в Application.Resources
файла App.xaml приведет к автоматическому применению шаблона в области приложения.
<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
.
Самый простой способ — определить шаблоны в словаре ресурсов App.xaml с помощью x:Key
, а затем выберите из них на основе условия.
DockingManger
принимает селектор шаблона, назначая свойство DockingManager.LayoutItemTemplateSelector
:
App.xaml
Определите явный DataTemplate
с помощью x:Key
:
<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
В следующем коде используется выражение Switch, доступное, начиная с C# 8.0. Его можно заменить оператором 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>
person
BionicCode
schedule
28.08.2020