Introduction

DirectoryTree.AutoCollapse is a DependencyProperty, if set to true, when chaning directory externally, will try to collapse unrelated directories (e.g. by setting SelectedDirectory), Default is true.

Design Changes

Before discussing DirectoryTree.AutoCollapse property, there’s a changes in DirectoryTree in 0.4, currently when a user select a directory in DirectoryTree, it will

  • set the DirectoryTree.SelectedDirectory, which will
  • trigger OnSelectedDirectoryChanged event, which is then
  • set the RootModel.SelectedDirectory
//Fixed DirectoryTree Collapse unrelated directory.
//public static void OnSelectedDirectoryChanged(DependencyObject sender,
//       DependencyPropertyChangedEventArgs args)
//{
// DirectoryTree dt = (DirectoryTree)sender;
// dt.RootModel.SelectedDirectory = args.NewValue as DirectoryInfoEx;
//}

This is not the planned way, so I have changed it so when DirectoryTreeItemViewModel.OnSelected() method is called, it will update RootModel.SelectedDirectoryModel, thus change the SelectedDirectory.

public override void OnSelected()
{
   ...
   (RootModel as DirectoryTreeViewModel).SelectedDirectoryModel = this;
}

Implementing AutoCollapse

You may wonder, why does it matter, the reason is that using the original method I have no way to identify whether the SelectedDirectory changes from outer or inner, but using the new way, it’s possible

public IDirectoryInfoExA SelectedDirectory
{
 set
 {
   if (AutoCollapse &&SelectedDirectoryModel != null
     && !SelectedDirectoryModel.EmbeddedDirectoryModel.EmbeddedDirectoryEntry.Equals(value))
       BroadcastCurrentDirectoryChanging(value);
   ....
 }
}

As you can see, if changes is inner, lets say, user change the selected directory using pointer,  it will change SelectedDirectoryModel first, thus wont call the BroadcastCurrentDirectoryChanging() method.  If the changes is outer, like using double-click a directory in file-list, it will trigger the method because SelectedDirectoryModel is not point to the same directory as the new SelectedDirectory.

The BroadcastCurrentDirectoryChanging() method, similar to BroadcastChange() method, will be sent to all loaded sub-items, except it will stop if the item is not expanded.

internal void BroascastCurrentDirectoryChanging(DirectoryInfoEx newDirectory)
{
 if (IsExpanded)
   if (this.EmbeddedDirectoryModel.EmbeddedDirectoryEntry.Equals(newDirectory) ||
     IOTools.HasParent(newDirectory, this.EmbeddedDirectoryModel.EmbeddedDirectoryEntry) ||
     IOTools.HasParent(this.EmbeddedDirectoryModel.EmbeddedDirectoryEntry, newDirectory))
   {
   if (IsLoaded)
     foreach (DirectoryTreeViewItemViewModel subItem in SubDirectories)
       subItem.BroascastCurrentDirectoryChanging(newDirectory);
 }
 else IsExpanded = false;
}

This will Collapse all unrelated directories (not same, not child of and not parent of), by calling IsExpanded = False.