I am trying to create a TreeView that can display items in a tree hirearchy. I want to be able to use code (C#) to expand and collapse TreeViewItems in the TreeView, through the properties bound to an ObservableCollection.
I have bound a property of my class to IsExpanded, and it seems to work if I set it BEFORE setting the tree's ItemSource - the newly created hierarchy will arrive pre-expanded.
But if I click a button that sets IsExpanded for an item in the collection, it does not expand or collapse the tree items in the GUI.
Here is an ugly screenshot of the program so far. The folders were manually created in an Initialize procedure.
Here is the TreeView xaml in the main window:
<TreeView x:Name="TheProjectTree" Margin="5" BorderBrush="{x:Null}" ItemsSource="{Binding DataSet}">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="{Binding Path=IsExpanded, Mode=TwoWay}" />
<!--<EventSetter Event="Expanded" Handler="TheProjectTreeItem_Expanded" />-->
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding nodes}">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Path=Icon}" Height="16"/>
<TextBlock Text=" " />
<TextBlock Text="{Binding Path=Name}" />
<TextBlock Text=" (" />
<TextBlock Text="{Binding Path=Type}" />
<TextBlock Text=")" />
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
Here is a MyProject class that has the data structures:
using System.Collections.ObjectModel;
namespace Project_X
{
public class MyProject
{
public ObservableCollection<MyNode> nodes;
public MyProject()
{
}
public void Initialize()
{
nodes = new ObservableCollection<MyNode>();
nodes.Add(new MyNode("Untitled Project", "Project"));
AddFolder("0. Initialize");
AddFolder("1. Reset");
AddFolder("2. Migrate");
}
public void AddFolder(string folderName)
{
nodes[0].nodes.Add(new MyProject.MyNode(folderName, "Folder"));
}
public class MyNode
{
public string Name { get; set; }
public string Type { get; set; }
public bool IsExpanded { get; set; }
public ObservableCollection<MyNode> nodes { get; set; }
public MyNode(string theName, string theType)
{
Name = theName;
Type = theType;
nodes = new ObservableCollection<MyNode>();
}
public string Icon
{
get
{
if (Type == "Project")
return "./graphics/icon_projectTree_small.png";
else if (Type == "Folder")
return "./graphics/icon_projectTree_small.png";
else if (Type == "Object")
return "./graphics/icon_projectTree_small.png";
else if (Type == "SQL")
return "./graphics/icon_projectTree_small.png";
else if (Type == "Text")
return "./graphics/icon_projectTree_small.png";
return "./graphics/icon_projectTree_small.png";
}
}
}
}
}
And finally, here is a little test procedure that I can call from a testing button.
private void NewProject()
{
Project = new MyProject(); // fire up the main project variable!
Project.Initialize(); // give it some dummy data!
Project.nodes[0].IsExpanded = true; // pre-expand the top-level project node
TheProjectTree.ItemsSource = Project.nodes; // assign the data set to the tree in the main window
Project.AddFolder("test"); // this works! adding new folders to the collection will show up in the GUI
Project.nodes[0].IsExpanded = true; // this does NOT work! it should collapse the top-levl project node in the tree, but it doesn't
}
I would greatly appreciate it if you could brow-beat some knowledge into me. I usually work in SQL, C# and .NET are not my strong suit. I spent the whole evening trying to wrap my head around MVVM and goodness I now feel like a really crummy programmer!