tags:

views:

1329

answers:

2

Hello, I'm just trying to find a way to control the expand / collapse of the treeview nodes through the object they're bound to. The object has an IsExpanded property, and I want to use that to show the treeview node itself expanded or collapsed based on that property.

Here's my code:

C#

    public partial class Window2 : Window
    {
     public Window2()
     {
      InitializeComponent();

      this.DataContext = new List<Parent>() { Base.GetParent("Parent 1"), Base.GetParent("Parent 2") };
     }
    }

    public class Base
    {
     public string Name { get; set; }
     public bool IsExpanded { get; set; }

     public static Parent GetParent(string name)
     {
      Parent p = new Parent() { Name = name };

      p.Children.Add(new Child() { Name = "Child 1", GrandChildren = new ObservableCollection<GrandChild>() { new GrandChild() { Name = "Grandchild 1" } } });
      p.Children.Add(new Child() { Name = "Child 2", GrandChildren = new ObservableCollection<GrandChild>() { new GrandChild() { Name = "Grandchild 1" } } });
      p.Children.Add(new Child() { Name = "Child 3", GrandChildren = new ObservableCollection<GrandChild>() { new GrandChild() { Name = "Grandchild 1" } } });

      return p;
     }
    }

    public class Parent : Base
    {
     public ObservableCollection<Child> Children { get; set; }

     public Parent()
     {
      this.Children = new ObservableCollection<Child>();
     }
    }

    public class Child : Base
    {
     public ObservableCollection<GrandChild> GrandChildren { get; set; }

     public Child()
     {
      this.GrandChildren = new ObservableCollection<GrandChild>();
     }
    }

    public class GrandChild : Base
    {
    }

XAML:

<Window x:Class="HeterogeneousExperimentExplorer.Window2"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:local="clr-namespace:HeterogeneousTree"
    Title="Window2" Height="300" Width="300">
    <Window.Resources>
     <HierarchicalDataTemplate DataType="{x:Type local:Parent}" ItemsSource="{Binding Children}">
      <TextBlock Text="{Binding Name}" />
      <HierarchicalDataTemplate.ItemTemplate>
       <HierarchicalDataTemplate DataType="{x:Type local:Parent}" ItemsSource="{Binding GrandChildren}">
        <TextBlock Text="{Binding Name}" />
        <HierarchicalDataTemplate.ItemTemplate>
         <DataTemplate>
          <TextBlock Text="{Binding Name}" />
         </DataTemplate>
        </HierarchicalDataTemplate.ItemTemplate>
       </HierarchicalDataTemplate>
      </HierarchicalDataTemplate.ItemTemplate>
     </HierarchicalDataTemplate>
    </Window.Resources>
    <Grid>
     <TreeView ItemsSource="{Binding}" />
    </Grid>
</Window>
+2  A: 

Came up with solution. Really simple:

 <Style TargetType="{x:Type TreeViewItem}">
  <Setter Property="IsExpanded" Value="{Binding IsNodeExpanded}">
  </Setter>
 </Style>

So the style gets the object bound to the TreeViewItem and looks at its IsNodeExpanded attribute and it assigns that value to the TreeViewItem.IsExpanded property. If you add Mode=TwoWay, they'll notify each other (TreeViewItem will tell the object when it has been expanded).

Thanks!

Carlo
A: 

FWIW, you may be interested in this CodeProject article by Josh Smith which shows how to create a MVVM based tree view using a generic (n-level) approach.

I'm not suggesting there is anything wrong with Carlo's implementation, but I found that article helpful in understanding the TreeView control, and MVVM in general.

Si