WPF: TabControl & DataTemplates - PullRequest
       6

WPF: TabControl & DataTemplates

31 голосов
/ 30 октября 2010

Я просто хочу понять следующий сценарий.Где я реализую <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> заполняет содержимое?

1 Ответ

52 голосов
/ 30 октября 2010

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

  • 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 используется для содержимого вкладок.

...