Usually when a UI displays a tree of files and folders, it doesn't scan the whole hierarchy in a single shot. Instead it gathers just enough information for the nodes that are expanded. Then when the user expands a node, it then goes to the effort of finding out what needs to be placed under that node.
The reason is simply because the number of files and directories on many people's system drives can get very large, and so your application will freeze up for a little while if they ask to see the root of drive C:.
It's slightly different depending on whether you're using WPF or Windows Forms. In WPF, the Expanded event is on the TreeViewItem
itself, whereas in Windows Forms there are several expansion events on the TreeView
(and no events on TreeNode
). But the pattern is much the same.
When you add a tree node that represents a folder, create a dummy node under it. Give it some special identification (a special flag in the Tag property, or perhaps a unique name that contains non-valid filesystem characters). This will allow the user to expand that node. Then in your expansion-event handler, look at the first child node - if it is the special dummy node, remove it and then create the real set of child nodes for that node. This will ensure that you only gather the real nodes one time per directory.
Here's a rough idea for WPF:
TreeViewItem folderNode = new TreeViewItem { Header = Path.GetFileName(folderPath) };
parentNode.Items.Add(folderNode);
// create the dummy item under it
TreeViewItem dummy = new TreeViewItem { Tag = _dummyTag };
folderNode.Items.Add(dummy);
folderNode.Expanded += delegate
{
if (folderNode.Items.Count == 1)
{
if (((TreeViewItem)folderNode.Items[0]).Tag == _dummyTag)
{
folderNode.Items.Clear();
CreateFolderChildren(folderNode, folderPath);
}
}
};
The _dummyTag can just be a field:
private static readonly object _dummyTag = new object();