И ItemTemplate, и ItemTemplateSelector установлены; ItemTemplateSelector будет игнорироваться

После этого вопроса у меня есть еще один вопрос о TreeView,

Что у меня уже есть TreeViewс HierarchicalDataTemplateв котором я могу изменить HierarchicalDataTemplate уровня 2 (как объяснено в вопросе и ответе).

Теперь я хочу изменить внешний вид расширителя Treeview, Для этого я определил ControlTemplate названный ctForTreeViewItemи я использую это так:

<Window.Resources>
    <ControlTemplate x:Key="ctForTreeViewItem"
                     TargetType="{x:Type TreeViewItem}">
        <Expander IsExpanded="True"
                  Background="Grey"
                  BorderBrush="Transparent"
                  Foreground="White"
                  BorderThickness="1,1,1,3">
            <Expander.Header>
                <Border BorderThickness="{TemplateBinding Border.BorderThickness}"
                        Padding="{TemplateBinding Control.Padding}"
                        BorderBrush="{TemplateBinding Border.BorderBrush}"
                        Background="{TemplateBinding Panel.Background}"
                        Name="Bd"
                        SnapsToDevicePixels="True"
                        Grid.Column="1">
                    <ContentPresenter Content="{TemplateBinding HeaderedContentControl.Header}"
                                      ContentTemplate="{TemplateBinding HeaderedContentControl.HeaderTemplate}"
                                      ContentStringFormat="{TemplateBinding HeaderedItemsControl.HeaderStringFormat}"
                                      ContentSource="Header"
                                      Name="PART_Header"
                                      HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
                                      SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
                </Border>
            </Expander.Header>

            <Expander.Content>
                <ItemsPresenter x:Name="ItemsHost" />
            </Expander.Content>

        </Expander>
    </ControlTemplate>

    <DataTemplate x:Key="Level3Template">
        <Border Background="LightBlue">
            <TextBlock Text="Level3"/>
        </Border>
    </DataTemplate>

    <HierarchicalDataTemplate x:Key="Level2RedTemplate"
                          ItemsSource="{Binding Value}"
                          ItemTemplate="{StaticResource Level3Template}">
        <Border Background="Red">
            <TextBlock Text="Level2"/>
        </Border>
    </HierarchicalDataTemplate>

    <HierarchicalDataTemplate x:Key="Level2YellowTemplate"
                          ItemsSource="{Binding Value}"
                          ItemTemplate="{StaticResource Level3Template}">
        <Border Background="Yellow">
            <TextBlock Text="Level2"/>
    </HierarchicalDataTemplate>

    <HierarchicalDataTemplate x:Key="Level1Template" 
                          ItemsSource="{Binding Value}"
                          ItemTemplateSelector="{StaticResource MySelector}">

        <HierarchicalDataTemplate.ItemContainerStyle>
            <Style TargetType="TreeViewItem">
                <Setter Property="Template"
                        Value="{StaticResource ctForTreeViewItem}" />
            </Style>
        </HierarchicalDataTemplate.ItemContainerStyle>

        <Border Background="Green">
            <TextBlock Text="Level1"/>
        </Border>
    </HierarchicalDataTemplate>
</Window.Resources>

<TreeView Grid.Row="1"
          Name="tv"
          ItemsSource="{Binding Items}"
          ItemTemplate="{StaticResource Level1Template}">
    <TreeView.ItemContainerStyle>
        <Style TargetType="TreeViewItem">
            <Setter Property="Template"
                    Value="{StaticResource ctForTreeViewItem}" />
        </Style>
    </TreeView.ItemContainerStyle>
</TreeView>

Это работает для уровня 1, как и ожидалось, поэтому на уровне 1 у меня есть TreeViewItems с определенным ControlTemplate и правильный HierarchicalDataTemplate,

Тем не менее, это не работает на уровне 2, где у меня есть ItemTemplateSelector, На этой позиции я получаю эту ошибку: System.Windows.Data Error: 25 : Both 'ItemTemplate' and 'ItemTemplateSelector' are set; 'ItemTemplateSelector' will be ignored.

  • Есть ли способ, которым я могу назначить ControlTemplate к TreeViewItemс, сохраняя при этом ItemTemplateSelector? Или даже

  • Есть ли другой способ, которым я могу изменить стиль экспандера TreeView?

1 ответ

Решение

Ваш элемент управления TreeViewItem ControlTemplate не работает. Он игнорирует селектор шаблона данных, потому что вы явно переопределяете это, устанавливая ContentTemplate на ContentPresenter, Это аналогично тому, что вызывает (безвредные) ошибки в вашем потоке вывода отладки: шаблоны уровня 2 наследуют ItemTemplateSelector от их предков, так же, как если бы вы установили ItemContainerStyle однажды на TreeView, он будет унаследован всеми потомками древовидной структуры, если какой-либо промежуточный потомок не переопределит его явно. Не нужно устанавливать его более одного раза. Потому что шаблоны уровня 2 наследуют ItemTemplateSelector и переопределить его другим свойством, вы получите ошибку, но это безвредно.

Я исправил шаблон элемента управления, изменив ContentPresenter для заголовка, чтобы он соответствовал стандартному шаблону элемента управления TreeViewItem: я удалил Content, ContentTemplate, а также ContentStringFormat атрибутов. ContentPresenter имеет поведение по умолчанию для всех этих вещей, поэтому вам не нужно указывать это явно.

<ContentPresenter 
    ContentSource="Header"
    Name="PART_Header"
    HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
    SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" 
    />

Ошибки шаблона / селектора шаблонов безвредны, но я смог их замолчать, установив ItemTemplateSelector явно обнулить на иерархических шаблонах данных уровня 2:

<HierarchicalDataTemplate 
    x:Key="Level2RedTemplate"
    ItemsSource="{Binding Value}"
    ItemTemplateSelector="{x:Null}"
    ItemTemplate="{StaticResource Level3Template}"
    >
    <Border Background="Red">
        <TextBlock Text="Level2"/>
    </Border>
</HierarchicalDataTemplate>
Другие вопросы по тегам