Introduction

This tree view control gives you the ability to control which drive types are displayed to let the user choose directories. A possible scenario is to show only local drives, because your Application scan the selected directories and fill a database with the generated meta data, and it makes no sense to allow directories from removable drives.

Design

Introduction

This release has a new design which is based on a tree view which aggregates a tree view data provider interface (Strategy pattern). The goal of the new design is to provide an easy way to extend or add data providers without changing a single line of tree view code. Basically the tree view interface will not change so far, but the data providers will change their behavior and features.

TreeViewFolderBrowser class defines the following core requirements

DriveTypes

RootFolder

CheckboxBehaviorMode

and is responsible to manage the checkboxes and the internal selected directories list.

ITreeViewFolderBrowserDataProvider is used by a TreeViewFolderBrowser instance and is responsible to

retrieve the computer drives and directories

Imagelist which is used to assign images to the nodes created by this instance

ContextMenu

and can provide custom features and behavior to extend the TreeViewFolderBrowser class.

TreeViewFolderBrowser

You can specify the drive types through a public instance property on the control. The enumeration can be treated as a bit field, that is, a set of flags.

Member Name

Description

NoRootDirectory

NoRootDirectory

RemovableDisk

Drive has removable media. This includes all floppy drives and many other varieties of storage devices.

LocalDisk

Drive has fixed (nonremovable) media. This includes all hard drives, including hard drives that are removable.

NetworkDrive

Network drives. This includes drives shared anywhere on a network.

CompactDisc

Drive is a CD-ROM. No distinction is made between read-only and read/write CD-ROM drives.

RAMDisk

Drive is a block of Random Access Memory (RAM) on the local computer that behaves like a disk drive.

The different CheckboxBehaviorMode indicates whether check boxes are displayed next to the tree nodes in the tree view control and how the tree view handle related events. The main difference between SingleChecked and RecursiveChecked behavior, lies in the fact that the user can't unselect sub folders of a checked folder in RecursiveChecked mode.

Member Name

Description

None

No check boxes are displayed next to the tree nodes in the tree view control.

SingleChecked

Check boxes are displayed next to the tree nodes in the tree view control. The user can check directories.

RecursiveChecked

Check boxes are displayed next to the tree nodes in the tree view control. The user can check directories, the subdirectories are checked recursive.

The root folder property let you specify where the browsing starts from. Root folder values are defined by System.Environment.SpecialFolder.

The tree view control shows the specified root folder, the drive types are ignored.

The combination of DriveType, CheckboxBehaviorModes and SpecialFolder enumeration values gives you the ability to control how the tree view display it's content and behaves when you select a directory.

DataProvider

Data providers are the workers behind the TreeViewFolderBrowser which controls them. By implementing the ITreeViewFolderBrowserDataProvider interface, you will have full control over the core processes like retrieving data, assign images to the nodes and provide custom ContextMenu items for each node. But you don't have to care about checkboxes, load on demand, find node at position if the user request the ContextMenu, you will be hooked if it's time to take some action on it. The only thing you must respect is the core functionality (DriveTypes and RootFolder) implemented by the TreeViewFolderBrowser.

To provide clean access to the handled TreeViewFolderBrowser class instance every method on the data provider interface provides an TreeViewFolderBrowserHelper class instance which lets you create nodes and give you access to the TreeViewFolderBrowser instance.

Please take a look at the two delivered standard implementations which can be found in the Raccoom.TreeViewFolderBrowser.DataProviders project.

Key features

TreeViewFolderBrowser

Different build in CheckboxBehaviorModes.

Step by step population for subdirectories.

Parent nodes are bold if there are selected subfolders, this helps to find selected directories in large structures.

Using the code

Before you begin make sure your project has a valid reference to the Raccoom.TreeViewFolderBrowser.dll. Go to the Toolbox window, right-click and select Customize Toolbox from the context menu. In the Customize Toolbox dialog go to the .NET Framework Components tab and select the Raccoom.TreeViewFolderBrowser.dll assembly that you just compiled. Now drop the TreeViewFolderBrowser control to your form.

This example assumes that you have created an instance of a TreeViewFolderBrowser control on a Form.

Remarks

This control display drive types and folders, so far so good. Removable disk's can change their medium and folders can change (new folder, delete folder) during run time, the control does not care about that.

I'm trying to get a context menu to show up when the user right-clicks anywhere in the control. Right now, it seems the MouseClick event fires only if the mouse is over text, but even then it doesn't display the context menu. Any tips?

Please check out the TreeViewFolderBrowserDataProviderShell32 source code. This class shows off how to invoke a custom context menu.

BTW: The TreeView creates an internal context menu instance which it will route to the attached data provider when the user right clicks on a node. Caused by the hit test it just shows off if the user clicks over a node rectangle.

I suspected it would be something simple.So it was all there all the time.

...

I tried it, and ...ShowFolder also has that bug mentioned in the other tread. - If I set the SelectedDirectories first and then show the folders all subfolders of checked folder get the checked mark, because GetSubDirs is not called.- If I show the folders first, then none of them gets the checked mark.

Maybe I should just add the GetSubDirs somewhere. I'll look into it.

My code works fine, because it expands the node before it is checked.And I altered the OnBeforeCheck as described in the other tread, so it would work fine even if the nodes don't get expanded.

at first, thanks for te great article and control. However, i encoutered some problems running the demo on Vista. The "Failed to get icon index" assertion is shown when the control is populating. The issue is caused by the fact that your code attempts to get icon for system folders like Control panel and the fileName variable in:SHGetFileInfo(fileName, dwAttr, ref shfi, shfiSize,((uint)(dwFlags) | (uint)iconState));equals a string like "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}"

Have you any thoughts on how to avoid the problem?

I think the problem could be solved by using PIDL instead of fileName, but i have no idea how to get PIDL for the FolderItem.

Show me a user that wants/needs to work with a million files at one moment in time ,) If one can't create/show so much files in one folder (OS Shell) why does one want to see them at one in a custom application? Where's the use case for your question?

Well you are right. I am working on a Backup application. The application facilitates user to take backup of folders/ directories of his choice. Therefore, we'll have to support files/folders in millions present in a folder/ directory as well. You are absolutely right about Shell, it hangs and very slow while enumerating large number of files. What is your advice to handle such a situation?

First I would investigate how good backup softwares today solved this kind of problem. Second I think no matter what kind of software you're writing the user will never need and wants to see thousands of files on the screen.

Strategies might be to create virtual groups for the files by - file extension- by alphabet starting letter- by Creation Date/Week/Year or a like

into a virtual folder and let the user expand just that folder providing just a minimal and also workable subset of the total files.

Maybe you better of providing a vista like instant search where the user can search/query for the files he needs to see?

Removable hard disks ( USB hard disk ) are being displayed even when selected drive type is Local Disk. This problem doesn't occur with removable flash drives. Have you also faced the same issue with this application?

In my application code also if I query win32_logicaldisk objects, win32_logicaldisk object coresponding to removable hardisk gives drive type = 3 ( that is for local disks ) while it should give 2. For removable flash drives the drivetype value is 2 as expected. I think that is the reason for the problem.

But i've a problem with the "recursive check". When I set the property: "CheckboxBehaviorMode" to "RecursiveChecked", I get the following:

Windows Vista

Standard Provider:* First click = select's the clicked folder plus all subfolders* Second click = deselect's all folders* After this, next click will only select the clicked folder without subfolders... :/

Shell32 Provider* Same behavior as above except, not expanded folders won't select his child's (I think it's a performance thing: You only load the childs of a folder when you click on it)

Windows Server 2003 & Windows XP

Standard Provider:* Works, but I can't uncheck a folder under the clicked folder

Shell32 Provider* Works also, but with the same Problem. Subfolders which aren't expanded won't be checked.

---

All testet with the demo version from here @codeProject. Does anyone have the same problem or maybe a easy fix?