Board index » delphi » TreeView Sorting

TreeView Sorting

Hi
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 make the search so the items get grouped first the folders
and then the files ( like Windows Explorer )

Note i don't like to use any other 3rd party componet.

I'm using Delphi 6 enterprice and Win2K.

Thanks.

 

Re:TreeView Sorting


Quote
In article <3e4ec97...@newsgroups.borland.com>, Efren Gonzalez wrote:
> 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 make the search so the items get grouped first the folders
> and then the files ( like Windows Explorer )

You have basically two options.

1) 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 <g>).

2) 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

  treeview1.items.beginupdate;
  try
    PopulateTreeView;
    treeview1.CustomSort( nil, 0 );
  finally
    treeview1.items.endupdate;
  end;

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:

procedure TForm1.TreeView1Compare(Sender: TObject; Node1, Node2:
TTreeNode;
  Data: Integer; var Compare: Integer);
begin
  If node1.Data = node2.Data Then
    compare := AnsiCompareText( Node1.Text, NOde2.Text )
  Else
    If Assigned( node1.data ) Then
      compare := -1  // folders sort before files
    Else
      compare := 1;
end;

--
Peter Below (TeamB)  
Use the newsgroup archives :
http://www.mers.com/searchsite.html
http://www.tamaracka.com/search.htm
http://groups.google.com
http://www.prolix.be

Re:TreeView Sorting


Thanks works OK

"Peter Below (TeamB)" <100113.1...@compuXXserve.com> wrote:

Quote
>In article <3e4ec97...@newsgroups.borland.com>, Efren Gonzalez wrote:
>> 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 make the search so the items get grouped first the folders
>> and then the files ( like Windows Explorer )

>You have basically two options.

>1) 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 <g>).

>2) 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

>  treeview1.items.beginupdate;
>  try
>    PopulateTreeView;
>    treeview1.CustomSort( nil, 0 );
>  finally
>    treeview1.items.endupdate;
>  end;

>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:

>procedure TForm1.TreeView1Compare(Sender: TObject; Node1, Node2:
>TTreeNode;
>  Data: Integer; var Compare: Integer);
>begin
>  If node1.Data = node2.Data Then
>    compare := AnsiCompareText( Node1.Text, NOde2.Text )
>  Else
>    If Assigned( node1.data ) Then
>      compare := -1  // folders sort before files
>    Else
>      compare := 1;
>end;

>--
>Peter Below (TeamB)  
>Use the newsgroup archives :
>http://www.mers.com/searchsite.html
>http://www.tamaracka.com/search.htm
>http://groups.google.com
>http://www.prolix.be

Other Threads