Author: Lou Adler
I'm populating a treeview from a folder location. At this moment I know how to scan
that folder for files and other folders. How can I perform a search so that the
items get grouped first the folders and then the files (like Windows Explorer)?
Answer:
You have basically two options:
Do two separate scans, one for folders only, one for files only. This way the
treeview gets populated in two chunks. But the two sections will not be sorted
alphabetically or so, since the order in which Findfirst/FindNext retrieves the
files/folders is undefined (or better: nobody outside MS knows how it is defined ).
or
Sort the treeview after you have populated it using a single scan. By blocking the
treeview from redrawing while you populate it (Items.beginUpdate/items.endupdate)
you can do populating and sorting without any visual upheaval.
You do the sorting by calling the handling CustomSort method of the treeview. There
are two ways to use it, you can hand it a custom comparison function or you can let
it call the treeviews OnCompare event to get a descision fromn you which node of a
pair to consider "larger". The second method may be easier for you, so you would
construct you treeview population code like
1 { ... }2 treeview1.items.beginupdate;
3 try4 PopulateTreeView;
5 treeview1.CustomSort(nil, 0);
6 finally7 treeview1.items.endupdate;
8 end;
9 { ... }
and handle the OnCompare event to compare two nodes. The comparison would inspect
two items of data for each node: whether it is a folder node or not, and the nodes
Text. So you need some way to indicate that a node stands for a folder. You could
use the nodes Data property for that, e.g. store Pointer(1) into it for a folder
and Nil (Pointer(0)) for a file. In this case the compare event handler would be
this:
10 11 procedure TForm1.TreeView1Compare(Sender: TObject; Node1, Node2: TTreeNode;
12 Data: Integer; var Compare: Integer);
13 begin14 if node1.Data = node2.Data then15 compare := AnsiCompareText(Node1.Text, NOde2.Text)
16 elseif Assigned(node1.data) then17 compare := -1 {folders sort before files}18 else19 compare := 1;
20 end;