Выделите TextBlock только в TreeViewItem с изображением

Итак, у меня есть TreeViewItem в следующем стиле:

                   <Style TargetType="{x:Type TreeViewItem}">
                        <Setter Property="HeaderTemplate">
                            <Setter.Value>
                                <DataTemplate>
                                    <StackPanel Orientation="Horizontal">
                                        <Image Name="img" Width="20" Height="16" Stretch="Uniform" Source="Images/Folder.png"/>
                                        <TextBlock Text="{Binding}" Margin="5,0" />
                                    </StackPanel>
                                </DataTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>

При выборе выделяются текстовый блок и изображение. Я пытаюсь просто выделить TextBlock, чтобы он работал как дерево папок в проводнике файлов.


person AKoran    schedule 09.11.2009    source источник


Ответы (2)


Я нашел (несколько хакерское), но легкое решение этой проблемы. Я вижу, что это довольно старый вопрос, но, тем не менее, я отправлю решение здесь, чтобы другие могли его найти.

В моем TreeView я переопределяю две кисти, используемые для установки фона TreeViewItem при изменении его выбора. Я также создаю копии кистей, чтобы потом восстановить их в моем шаблоне данных:

<TreeView ItemsSource="{Binding Path=SomeDataSource}">
    <TreeView.Resources>
         <SolidColorBrush x:Key="_CustomHighlightBrushKey" Color="{Binding Source={StaticResource {x:Static SystemColors.HighlightBrushKey}}, Path=Color}" />
         <SolidColorBrush x:Key="_CustomControlBrushKey" Color="{Binding Source={StaticResource {x:Static SystemColors.ControlBrushKey}}, Path=Color}" />
         <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent" />
         <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent" />
    </TreeView.Resources>
</TreeView>

Обратите внимание, что мне не удалось заставить это работать с привязкой DynamicResource, поэтому это решение, вероятно, не будет работать с изменениями темы. Мне было бы очень интересно узнать, есть ли способ сделать это.

Затем я использую следующий шаблон иерархических данных для форматирования узлов дерева:

<HierarchicalDataTemplate DataType="{x:Type SomeViewModelType}" ItemsSource="{Binding Path=Children}">
    <StackPanel Orientation="Horizontal">
        <StackPanel.Resources>
            <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="{Binding Source={StaticResource {x:Static SystemColors.HighlightBrushKey}}, Path=Color}" />
            <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="{Binding Source={StaticResource {x:Static SystemColors.ControlBrushKey}}, Path=Color}" />
        </StackPanel.Resources>
        <Image SnapsToDevicePixels="True" Source="...">
        </Image>
        <TextBlock Text="{Binding Path=DisplayName}" Margin="5,0">
            <TextBlock.Resources>
                <Style TargetType="{x:Type TextBlock}">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeViewItem}}, Path=IsSelected}" Value="True">
                            <Setter Property="Background" Value="{DynamicResource _CustomHighlightBrushKey}" />
                        </DataTrigger>
                        <MultiDataTrigger>
                            <MultiDataTrigger.Conditions>
                                <Condition Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeViewItem}}, Path=IsSelected}" Value="True" />
                                <Condition Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeViewItem}}, Path=IsSelectionActive}" Value="False" />
                            </MultiDataTrigger.Conditions>
                            <Setter Property="Background" Value="{DynamicResource _CustomControlBrushKey}" />
                        </MultiDataTrigger>
                    </Style.Triggers>
                </Style>
            </TextBlock.Resources>
        </TextBlock>
    </StackPanel>
</HierarchicalDataTemplate>

Обратите внимание, что я восстанавливаю системные кисти до их исходных (статических) значений, чтобы контекстные меню отображались правильно.

person Ulrik Rasmussen    schedule 23.10.2011

Вам нужно будет свернуть свою собственную отметку выделения, поэтому вместо того, чтобы позволить элементу управления закрашивать весь фон панели синим, вы устанавливаете собственное форматирование выделения на основе триггера, когда TreeViewItem.IsSelected имеет значение True.

В вашем случае это будет установка фона контейнера текста на синий (если он установлен, обычно белый) и оставить фон контейнера изображения белым, в то время как общий фон контейнера будет белым.

Метод описан здесь: текст ссылки

person Guy    schedule 09.11.2009
comment
В этом есть смысл, но это не так просто, как в приведенном вами примере. Каждый раз, когда я пытаюсь использовать TargetName для адресации TextBlock, я получаю сообщение об ошибке, что к нему нельзя получить доступ. - person AKoran; 10.11.2009
comment
stackoverflow.com/questions/248545/ - person Guy; 10.11.2009
comment
Не поймите неправильно, но новичку в WPF это не очень поможет, когда вы укажете пример, который как бы близок к тому, что я пытаюсь сделать. Независимо от того, что я пытаюсь, каждый раз, когда я возвращаюсь к TextBlock, я получаю, что свойство TargetName не может быть установлено при ошибке Style Setter. - person AKoran; 10.11.2009
comment
Я думаю, что причина, по которой вы получаете эту ошибку, заключается в том, что установщик стиля всегда устанавливает свойство элемента управления, который использует этот стиль, который может быть перенаправлен свойством TargetName. Если вы посмотрите на первый опубликованный мною пример, триггер не является частью стиля, это просто часть шаблона управления, и я думаю, что здесь вы ошибаетесь. - person Guy; 11.11.2009