When either of the delete options is used, each works correctly, but the TreeView object doesn’t correctly reflect the updated structure and neither does the internal structure.
We’ll attack these separately, handling the internal structure first (for reasons that will soon become apparent). To delete a file or directory from the internal structure, you need to find the parent of that item and then delete the node from the parent’s file or directory list (as appropriate).
The internal structure doesn’t have any back reference, so if you were to do the delete based only on that structure, you’d have to search for the node from the root. Luckily, the TreeNode objects do have such links, so you’ll merely get the parent of the selected node and then tell the parent DirectoryNode to delete the selected node.
Deleting the contents of a directory is easier; you merely modify the DeleteContents() method on DirectoryNode to clear the files and dirs arrays.
That finishes updating the nodes of the internal structure, but now that the nodes have been removed, the cached sizes along the modified path (from the deleted nodes up to the root) are incorrect. To update these, we originally planned on traversing the modified path and modifying the sizes based on the changed values. After a bit of reflection, however, we decided to do the brute-force method and added the ClearSizeCache() to the DirectoryNode class; this method merely resets the sizes on all the directories to null, forcing them to be recalculated when they’re requested through the properties.
You’re now ready to update the tree so it reflects the new state. Removing a node from the TreeView is as simple as calling the Remove() function.
Finally, you need to update the sizes on the displayed nodes. You can do this in the UpdateTreeNodes() member on the form. This member takes a collection of nodes and updates the text for each of them (which will indirectly cause the sizes to be recalculated).
That’s it—you now can delete files from the structure and have the TreeView always show you the proper information.
However, if you load an existing baseline and then delete files, you’ll notice that the comparison is no longer correct.
1. A Bit of Refactoring
Our initial view of the display of ratios (and the color-coding) of directories and files was that they’d be static, which was why the DirectoryNode stored the ratio rather than calculating it when needed. In retrospect, this was a poor decision, since we knew we’d want to delete files later. Mea culpa.
After exploring updating the ratio when necessary (an ugly task), we decided to have the DirectoryNode store a reference to the corresponding baseline DirectoryNode and then calculate the ratio when it was requested.
The change to the DirectoryNode class simplifies the code elsewhere, and the percentages are now updated correctly. Another problem appears, however; the “pie chart” coding of the icons doesn’t get updated correctly when a file is deleted. A look at the current code shows that the form calculates the fraction when the tree is populated. Adding code to update this—and to get it right—seems to be decidedly nontrivial.
An alternate approach is to have a file or directory calculate the fraction directly, based on the parent’s size. Doing this will require that files and directories be able to easily get to their parents, and the easiest way to do that is to add a Parent property to the BaseNode class. This enables calculating the fraction on the fly and finally allows you to get the behavior you want. It also allows a directory or file to be able to delete itself from the parent directory, which eliminates the code that walked the tree to do this.
Source: Gunnerson Eric, Wienholt Nick (2005), A Programmer’s Introduction to C# 2.0, Apress; 3rd edition.