WPF - Good Way to take a list to a Tree
c#, list, listview, tree, wpf
Solution
This will take your list of strings and turn it into a tree suitable for viewing with TreeView as you described:
public IList BuildTree(IEnumerable<string> strings)
{
return
from s in strings
let split = s.Split("/")
group s by s.Split("/")[0] into g // Group by first component (before /)
select new
{
Name = g.Key,
Children = BuildTree( // Recursively build children
from s in grp
where s.Length > g.Key.Length+1
select s.Substring(g.Key.Length+1)) // Select remaining components
};
}
This will return a tree of anonymous types, each containing a Name property and a Children property. This can be bound directly to the `TreeView` by specifying a `HierarchicalDataTemplate` with `ItemsSource="{Binding Children}"` and content consisting of a `<TextBlock Text="{Binding Name}">` or similar.
Alternatively you could define a tree node class in code if you want additional members or semantics. For example, given this node class:
public class Node
{
public string Name { get; set; }
public List<Node> Children { get; set; }
}
your BuildTree function would be slightly different:
public List<Node> BuildTree(IEnumerable<string> strings)
{
return (
from s in strings
let split = s.Split("/")
group s by s.Split("/")[0] into g // Group by first component (before /)
select new Node
{
Value = g.Key,
Children = BuildTree( // Recursively build children
from s in grp
where s.Length > g.Key.Length+1
select s.Substring(g.Key.Length+1)) // Select remaining components
}
).ToList();
}
Again this can be bound directly using a `HierarchicalDataTemplate`. I generally use the first solution (anonymous types) unless I want to do something special with the tree nodes.
Problem
I have a list that looks like this: ``` Base/Level1/Item1 Base/Level1/Item2 Base/Level1/Sub1/Item1 Base/Level2/Item1 Base/Level3/Sub1/Item1 ``` I would like an easy way put that into a ListView. (Ie similar to this) ``` Base | +->Level1 | | | +=Item1 | +=Item2 | | | +->Sub1 | | | +=Item1 | +->Level2 | | | +=Item1 | +->Level3 | +->Sub1 | +=Item1 ``` Is there an established way to make this kind of conversion or do I just need to roll my own parser? (In case it may be relevant the real items in my code are TFS Iteration Paths.)