QbDirectoryViz

WPF = RAD

As I was working on an unrelated project for work, I thought it would be easy to somehow visualize relative directory and file usage for a particular directory just by using a little recursion and a HierarchicalDataTemplate. I went ahead and wrote the small utility, which is not that impressive by itself. What I believe is impressive is how little work and how easy it is to do using WPF.

When started, the tool will start analyzing the directory in which it started and then all subdirectories. It will calculate sizes for each directory and sort the results for each directory in descending order by size. Progress bars show a file or directory’s usage percent compared to others in the same directory.

Here is my blog’s research folder:

By expanding and collapsing nodes it is easy to see the relative disk usage of directories and files. While this tool is not going to replace any of the other famous directory visualization tools out there, it just shows how WPF + 1 hour can go a long way.

There are three classes that make up nodes in the tree:

FileSystemTreeNode – An abstract class that contains the node’s name and size
DirectoryInfoTreeNode – Derives from FileSystemTreeNode and adds capability for children
FileInfoTreeNode – Derives from FileSystemTreeNode but adds no extra functionality

By building a tree consisting of these nodes (which are just data objects and not visual in any way), they can be visualized using a HierarchicalDataTemplate:

<HierarchicalDataTemplate DataType=”{x:Type qb:DirectoryInfoTreeNode}” ItemsSource=”{Binding Path=Children}”>
<StackPanel Orientation=”Horizontal”>
<Image Width=”16″ Height=”16″ Source=”CLSDFOLD.BMP”/>
<ProgressBar Margin=”2,0,2,0″ Value=”{Binding Path=Size, Mode=OneWay}” Minimum=”0″ Maximum=”{Binding Path=ParentSize}” Width=”100″/>
<TextBlock Margin=”0,0,5,0″ Text=”{Binding Path=Size}” Width=”75″ TextAlignment=”Right”/>
<TextBlock Margin=”1,0,1,0″ Text=”{Binding Path=Name}”/>
</StackPanel>
</HierarchicalDataTemplate>
<DataTemplate DataType=”{x:Type qb:FileInfoTreeNode}”>
<StackPanel Orientation=”Horizontal”>
<Image Width=”16″ Height=”16″ Source=”DOC.BMP”/>
<ProgressBar Margin=”2,0,2,0″ Value=”{Binding Path=Size, Mode=OneWay}” Minimum=”0″ Maximum=”{Binding Path=ParentSize}” Width=”100″/>
<TextBlock Margin=”0,0,5,0″ Text=”{Binding Path=Size}” Width=”75″ TextAlignment=”Right”/>
<TextBlock Text=”{Binding Path=Name}”/>
</StackPanel>
</DataTemplate>

In reality, only the DirectoryInfoTreeNode uses a HierarchicalDataTemplate since it contains children while the FileInfoTreeNode does not. The FileInfoTreeNode just uses a similar looking DataTemplate.

I cringe when I see people manually build WPF trees by using the WPF TreeNode or deriving from it. There may be scenarios that require such a design, but I strongly suggest trying to separate the data from the UI if possible using data templates. Many people often put a lot of logic into their tree nodes as well. I admit I had the tree building logic in the DirectoryInfoTreeNode initially at first, until I realized I would have no support for showing progress or cancelation. Instead I pulled the logic out and put it into a FileSystemTreeBuilder class that could do the processing on a background thread and not lock up the UI. I modified last week’s IProgressOperation to instead be an abstract base class that would do the work of creating the worker thread and supporting the necessary bindings for the ProgressWindow.

There isn’t anything really magical about the tool, but I would hate to have tried to implement it using MFC or even C#.

—Update—

Michael Kennedy decided to add a few features to QbDirectoryViz:

-Better directory size text (KB, MB, GB)
-Ability to specify folder path
-ProgressBar not shown in taskbar

You can download the source to version 1.1 here: QbDirectoryViz 1.1