Change TreeViewItem Template when IsSelected and two types using in TreeView

青春壹個敷衍的年華 提交于 2020-01-23 01:27:04

问题


In my TreeView I use two differnt classes for binding. For example, I have a Group what can have ChildGroup and can have Items. Example code of this classes:

using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace WpfApplication1
{
public class Group
{
    public Group(string name)
    {
        Name = name;
        items = new ObservableCollection<Item>();
        groups = new ObservableCollection<Group>();
    }
    public string Name { get;
        set;
    }

    private ObservableCollection<Item> items;
    private ObservableCollection<Group> groups;

    public ObservableCollection<Item> Items
    {
        get { return items; }
    }


    public ObservableCollection<Group> Groups
    {
        get { return groups; }
    }

    public IEnumerable<object> AllItems
    {
        get
        {
            foreach (var group in groups)
            {
                yield return group;
            }
            foreach (var item in items)
            {
                yield return item;
            }
        }
    }

}

public class Item
{
    public Item(string name)
    {
        ItemName = name;
    }

    public string ItemName
    {
        get;
        set;
    } 
}
}

To bind it to TreeView I use following template

<Grid>
    <TreeView Name="treeView">
        <TreeView.Resources>
            <HierarchicalDataTemplate DataType="{x:Type WpfApplication1:Group}"
                                      ItemsSource="{Binding AllItems}">
                <TextBlock Text="{Binding Name}"/>
            </HierarchicalDataTemplate>
            <DataTemplate DataType="{x:Type WpfApplication1:Item}">
                <TextBlock Text="{Binding ItemName}" FontStyle="Italic"/>
            </DataTemplate>
        </TreeView.Resources>
    </TreeView>
</Grid>

It is easy.

The problem is that I need to change ItemTemplate when Is selected. And I need to change only then Item class selected.

I can do it if only one class use for binding. It also easy using Style and Trigger, like this:

<TreeView Name="treeView1" Grid.Column="1">
        <TreeView.Resources>
            <HierarchicalDataTemplate DataType="{x:Type WpfApplication1:Group}"
                                      ItemsSource="{Binding AllItems}"
                                      x:Key="groupTemplate">
                <TextBlock Text="{Binding Name}"/>
            </HierarchicalDataTemplate>
            <HierarchicalDataTemplate DataType="{x:Type WpfApplication1:Group}"
                                      ItemsSource="{Binding AllItems}"
                                      x:Key="selectedGroupTemplate">
                <TextBlock Text="{Binding Name}" FontStyle="Italic" FontWeight="Bold" FontSize="14"/>
            </HierarchicalDataTemplate>
        </TreeView.Resources>

        <TreeView.ItemContainerStyle>
            <Style TargetType="{x:Type TreeViewItem}">
                <Setter Property="HeaderTemplate" Value="{StaticResource groupTemplate}"/>
                <Style.Triggers>
                    <Trigger Property="IsSelected" Value="True">
                        <Setter Property="HeaderTemplate" Value="{StaticResource selectedGroupTemplate}"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </TreeView.ItemContainerStyle>
    </TreeView>

But I have a trouble for multiclass binding.

How can I change SelectedItem template then multiclass binding using? Any ideas?

My code behind sample:

using System.Collections.ObjectModel;
using System.Windows;

namespace WpfApplication1
{
/// <summary>
/// Interaction logic for Window2.xaml
/// </summary>
public partial class Window2 : Window
{
    private ObservableCollection<Group> _groups;
    public ObservableCollection<Group> Groups
    {
        get { return _groups; }
    }

    public Window2()
    {
        InitializeComponent();

        InitGroups();

        treeView.ItemsSource = _groups;
        treeView1.ItemsSource = _groups;
    }

    private void InitGroups()
    {
        _groups = new ObservableCollection<Group>();

        Group group1 = new Group("Group1");
        group1.Groups.Add(new Group("Group1.1"));
        group1.Groups.Add(new Group("Group1.2"));
        group1.Groups.Add(new Group("Group1.3"));

        group1.Items.Add(new Item("Item1.1"));
        group1.Items.Add(new Item("Item1.2"));

        group1.Groups[1].Items.Add(new Item("Item1.2.1"));
        group1.Groups[1].Items.Add(new Item("Item1.2.2"));


        _groups.Add(group1);

        Group group2 = new Group("Group2");
        group2.Groups.Add(new Group("Group2.1"));
        group2.Groups.Add(new Group("Group2.2"));

        group2.Items.Add(new Item("Item2.1"));
        group2.Groups[0].Items.Add(new Item("Item2.1.1"));
        group2.Groups[0].Items.Add(new Item("Item2.1.1"));

        _groups.Add(group2);
    }
}
}

Result

Now I think to use TreeView.HeaderTemplateSelector, but may be exists way to use only xaml.

Thanks.


回答1:


There are a number of ways to acheive your desired result. If you are sure that your DataTemplate will only be used in TreeViewItem objects, then the easiest is simply to bind directly to the TreeViewItem.IsSelected property and then react to the change in your DataTemplate:

    <DataTemplate DataType="{x:Type WpfApplication1:Item}">
        <TextBlock Text="{Binding ItemName}">
            <TextBlock.Style>
                <Style>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding IsSelected, RelativeSource=
{RelativeSource FindAncestor, AncestorType={x:Type TreeViewItem}}, FallbackValue=False}" 
Value="True">
                            <Setter Property="TextBlock.FontStyle" Value="Italic" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </TextBlock.Style>
        </TextBlock>
    </DataTemplate> 


来源:https://stackoverflow.com/questions/9123608/change-treeviewitem-template-when-isselected-and-two-types-using-in-treeview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!