In my TreeView, I use two differnt classes for binding. For example, I have a group that can have a child group and can contain elements. Sample code for this class:
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 associate it with a TreeView, I use the 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 the ItemTemplate when selecting. And I need to change only when the Item class is selected.
I can do this if only one class is used for binding. It is also easy to use style and trigger, for example:
<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 problem with multiclass binding.
How can I change the SelectedItem template and then use multiclass binding? Any ideas?
My code is for the 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 am thinking of using TreeView.HeaderTemplateSelector, but there may be a way to use only xaml.
Thanks.