Подтвердить что ты не робот

WPF: TabControl & DataTemplates

Я просто хочу понять следующий сценарий. Где я реализую <TabControl>, связанный с ObservableCollection<TabViewModel>

Нет шаблонов данных

Когда у меня нет DataTemplate s, текст WpfApplication1.TabViewModel появляется в заголовке и контенте. Хорошо, я понимаю эту часть.

Просто ItemTemplate

Когда у меня только

<TabControl.ItemTemplate>
    <DataTemplate>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding TabTitle}" />
        </StackPanel>
    </DataTemplate>
</TabControl.ItemTemplate>

Затем заголовок моей вкладки заполняется. Содержимое вкладки все еще WpfApplication1.TabViewModel.

Просто DataTemplate

Когда у меня есть только что ниже в <Window.Resources>

<DataTemplate DataType="{x:Type local:TabViewModel}">
    <TextBox Text="{Binding Text}" />
</DataTemplate>

Эти шаблоны заполняют заголовок вкладки.

И

Когда у меня есть оба, ItemTemplate заполняет заголовок вкладки, а DataTemplate заполняет содержимое вкладки. Почему все это различие. ItemTemplate и DataTemplate заполняет заголовок вкладки, если другой нет. Если оба присутствуют, ItemTemplate заполняет заголовок, а DataTemplate заполняет содержимое.

Хотя у меня все работает, я очень смущен. Не должно ли что-то вроде <TabControl.HeaderTemplate> заполнять заголовок и <TabControl.ItemTemplate> заполнять контент?

4b9b3361

Ответ 1

Прежде всего, здесь задействованы два шаблона:

  • TabControl.ItemTemplate, используемый для отображения заголовков TabItem
  • TabControl.ContentTemplate, используемый для отображения содержимого TabItem

Если вы не зададите эти свойства явно, WPF попытается разрешить их в другом месте. Он будет подниматься по логическому дереву, ища ресурс, рассказывающий, как визуализировать вашу модель представления. Если он найдет DataTemplate, у которого есть соответствующий DataType, но нет ключа, он будет использовать его для рендеринга модели представления. Если он не найдет его, он по умолчанию будет отображать значение ToString объекта.

Итак, если вы хотите быть явным, вам нужно что-то вроде этого:

<TabControl ItemsSource="{Binding Tabs}">
    <TabControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding TabTitle}"/>
        </DataTemplate>
    </TabControl.ItemTemplate>
    <TabControl.ContentTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Text}"/>
        </DataTemplate>
    </TabControl.ContentTemplate>
</TabControl>

Поскольку вы не являетесь конкретным, WPF пытается подойти к вашему логическому дереву, чтобы найти подходящий DataTemplate. Когда он находит это, он использует его для рендеринга модели представления. Если он не находит его, он вызывает ToString и отображает это.

Итак, чтобы ответить на ваши конкретные случаи:

Только ItemTemplate

Вы явно указали, как создавать заголовки заголовков, но не содержимое табуляции. Таким образом, первая выполняется с помощью предоставленного DataTemplate, но по умолчанию будет ToString.

Только DataTemplate

Вы явно не указали, как отображать заголовки табуляции или содержимое табуляции. Поэтому WPF ищет подходящий DataTemplate для обоих. Поскольку оба содержат экземпляр вашей модели представления (что их DataContext), то тот же DataTemplate будет использоваться для отображения заголовков вкладок и их содержимого.

ПРИМЕЧАНИЕ. Вы явно не указали, что это то, что происходит в вашем вопросе. Исправьте меня, если я ошибаюсь.

И

В этом случае вы явно указали, как создавать заголовки заголовков, но не содержимое табуляции. Поэтому явный DataTemplate используется для заголовков табуляции, а неявный DataTemplate используется для содержимого вкладки.