Monday, 10 October 2011

WPF: TreeView example (Part 4)

In the example shown in Part 3, we saw how to show a tree, with depth of 3.

But what about scenarios, where we do not really know the depth of the tree? Best example is Windows Explorer, it shows a tree with folders, sub-folders, more sub-folders and so on. How do build such a tree?

Let’s try to implement this. We create a class Folder:

    public class Folder
    {
        public string Name
        {
            get
            {
                if (!String.IsNullOrEmpty(Path))
                {
                    return io.Path.GetFileName(Path);
                }
                return null;
            }
        }
        public string Path
        { get; set; }
        public List<Folder> Folders
        { get; set; }
        public Folder()
        {
            Folders = new List<Folder>();
        }
        public static Folder CreateFolderTree(string rootFolder)
        {
            Folder fld = new Folder { Path = rootFolder };
            foreach (var item in io.Directory.GetDirectories(rootFolder))
            {
                fld.Folders.Add(CreateFolderTree(item));
            }
            return fld;
        }
    }

XAML:

        <TreeView Name="tv" ItemsSource="{Binding}" Background="Beige">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding Path=Folders}">
                    <Border BorderBrush="BurlyWood" BorderThickness="1">
                        <TextBlock Text="{Binding Path=Name}" />
                    </Border>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>

Loading data (in Window.cs):

List<Folder> folders = new List<Folder>();
folders.Add(Folder.CreateFolderTree(@"C:\WPFTest"));
tv.DataContext = folders;
Output:

image

In Windows explorer:

image 

So what changed here? The code generating business class is more or less same, the major change is in XAML. You will notice:

> We are using only a single HierarchicalDataTemplate. The display logic for each item uses the property – “Name”.
> We do specify the ItemsSource property but do not specify an ItemTemplate. This is the way of telling WPF that - the children of this TreeViewItem are in the ‘Folders’ property, however as I have not specified the ItemTemplate, please reuse the one I am using.
> We can use ‘Folders’ and ‘Name’ property without any problem because all the objects in the tree view are of same type – Folder.

And voila! We get to use the same HierarchicalDataTemplate for both the parent and its children.

Now the question is, what if we want to use different property for display – in parent and children? For instance, how do we show full folder path in the parent node, but just the folder name in the child?

No comments:

Post a Comment

Note: only a member of this blog may post a comment.