none
Стиль выделения для TreeViewItem на WPF

    Вопрос

  • Доброго времени суток, в программе используется элемент управления TreeView для которого создан шаблон вида:

    <HierarchicalDataTemplate x:Key="MainTreeTemplate" ItemsSource="{Binding Childs}">
            <WrapPanel Orientation="Horizontal">
                <WrapPanel.ContextMenu>
                    <ContextMenu ItemsSource="{Binding ContextMenu, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
                </WrapPanel.ContextMenu>
                <Image Width="16" Height="16" Source="{Binding TypeImage, Converter={StaticResource ImageConvertor}}" Margin="0,0,5,0"/>
                <Image Width="16" Height="16" Source="{Binding StateImage, Converter={StaticResource ImageConvertor}}"  Margin="0,0,5,0"/>
                <TextBlock TextWrapping="Wrap" Text="{Binding Name, Mode=Default}"/>
            </WrapPanel>
    </HierarchicalDataTemplate>
    При выделении элемента дерева представленного этим шаблоном он выделяется полностью вместе с 2 картинками (элементы управления Image) скажите пожалуйста как сделать так чтобы при выделении выделялся только текст (элементы управления TextBlock).


    21 декабря 2016 г. 6:54

Ответы

  • Как то так:

    <Window x:Class="WpfApplication3.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApplication3"
            mc:Ignorable="d"
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
            <local:IsSelectedToBrushConverter x:Key="IsSelectedToBrushConverter" />
        </Window.Resources>
        <Grid>
            <TreeView ItemsSource="{Binding Source={x:Static local:Model.DemoData}}">
                <TreeView.Resources>
                    <Style TargetType="TreeViewItem">
                        <Style.Resources>
                            <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent"/>
                            <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black"/>
                        </Style.Resources>
                        <Setter Property="IsSelected" Value="{Binding IsSelected}" />
                    </Style>                
                </TreeView.Resources>
                <TreeView.ItemTemplate>
                    <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                        <StackPanel Orientation="Horizontal">
                            <Image Source="Images/snowflake.PNG" Width="20" />
                            <TextBlock Text="{Binding Name}" Background="{Binding IsSelected,Converter={StaticResource IsSelectedToBrushConverter}}" />
                            <Image Source="Images/snowflake.PNG" Width="20" />
                        </StackPanel>
                    </HierarchicalDataTemplate>
                </TreeView.ItemTemplate>
            </TreeView>
        </Grid>
    </Window>

    C небольшими комментариями можно посмотреть здесь.

    Выглядит вот так:



    23 декабря 2016 г. 13:58
    Отвечающий

Все ответы

  • Добрый день.

    При применении DataTemplate компонент оборачивает то что вы в нем прописали в обертку характерную для контрола показа коллекций. В вашем случае, такой оберткой является TreeViewItem. Вам нужно переопределить стиль на него нацеленный, чтобы он не подсвечивал выбранный элемент. А у вашего TextBlock-а надо наоборот сделать такую подсветку. Скорее всего вам придется сделать или сложный Binding, чтобы пробросить признак IsSelected из родительского TreViewItem в TextBlock, или добавить свойство для хранения этого признака в модель (или обертку вокруг модели), в которую это свойство будет пробрасываться из TreViewItem, а потом забираться TextBlock-ом. Пример такой обертки можете посмотреть здесь.

    22 декабря 2016 г. 5:44
    Отвечающий
  • Спасибо за ответ, у меня как раз свойство  IsSelected хранится в моделе и связано с моделью так как в указанном вами примере. Отследить что элемент выбран не проблема, беда в том что я не понимаю как переопредилить стиль TreViewItem таким образом чтобы  он не подсвечивал выбранный элемент и в тоже время подсвечивался TextBlock при IsSelected = true. Я так полагаю это 2 разных стиля один для TreViewItem другой для TextBlock.

    • Изменено Snak2013 23 декабря 2016 г. 7:08
    23 декабря 2016 г. 7:07
  • Как то так:

    <Window x:Class="WpfApplication3.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApplication3"
            mc:Ignorable="d"
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
            <local:IsSelectedToBrushConverter x:Key="IsSelectedToBrushConverter" />
        </Window.Resources>
        <Grid>
            <TreeView ItemsSource="{Binding Source={x:Static local:Model.DemoData}}">
                <TreeView.Resources>
                    <Style TargetType="TreeViewItem">
                        <Style.Resources>
                            <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent"/>
                            <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black"/>
                        </Style.Resources>
                        <Setter Property="IsSelected" Value="{Binding IsSelected}" />
                    </Style>                
                </TreeView.Resources>
                <TreeView.ItemTemplate>
                    <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                        <StackPanel Orientation="Horizontal">
                            <Image Source="Images/snowflake.PNG" Width="20" />
                            <TextBlock Text="{Binding Name}" Background="{Binding IsSelected,Converter={StaticResource IsSelectedToBrushConverter}}" />
                            <Image Source="Images/snowflake.PNG" Width="20" />
                        </StackPanel>
                    </HierarchicalDataTemplate>
                </TreeView.ItemTemplate>
            </TreeView>
        </Grid>
    </Window>

    C небольшими комментариями можно посмотреть здесь.

    Выглядит вот так:



    23 декабря 2016 г. 13:58
    Отвечающий
  • Спасибо большое, очень помогло.
    26 декабря 2016 г. 12:18
  • Пожалуйста, обращайтесь :)
    26 декабря 2016 г. 12:45
    Отвечающий