Articles   Members Online: 3
-Article/Tip Search
-News Group Search over 21 Million news group articles.
-Delphi/Pascal
-CBuilder/C++
-C#Builder/C#
-JBuilder/Java
-Kylix
Member Area
-Home
-Account Center
-Top 10 NEW!!
-Submit Article/Tip
-Forums Upgraded!!
-My Articles
-Edit Information
-Login/Logout
-Become a Member
-Why sign up!
-Newsletter
-Chat Online!
-Indexes NEW!!
Employment
-Build your resume
-Find a job
-Post a job
-Resume Search
Contacts
-Contacts
-Feedbacks
-Link to us
-Privacy/Disclaimer
Embarcadero
Visit Embarcadero
Embarcadero Community
JEDI
Links
How to build a TTreeView from a file Turn on/off line numbers in source code. Switch to Orginial background IDE or DSP color Comment or reply to this aritlce/tip for discussion. Bookmark this article to my favorite article(s). Print this article
31-Oct-02
Category
Files Operation
Language
Delphi 2.x
Views
98
User Rating
No Votes
# Votes
0
Replies
0
Publisher:
DSP, Administrator
Reference URL:
DKB
			Author: Tomas Rutkauskas

I would like to populate a TTreeView from a simple file with the following structure

Key: Integer (unique)
Name: String (description)
Parent: Integer (key of parent in treeview)

I assume that the key and parent fields are all I need to build the treeview 
(parent = 0 would be a root node)

Answer:

I would break this down into two steps:

1) Read the file into memory
2) Populate the treeview using a recursive function


1) One method of doing this would be by building a TCollection/ TCollectionItem 
pair of classes. The TCollectionItems just need three fields:

1   TInputItem = class(TCollectionItem)
2   private
3     fKey: integer;
4     fName: string;
5     fParent: integer;
6   public
7     property Key: integer read fKey write fKey;
8     property Name: string read fName write fName;
9     property Parent: integer read fParent write fParent;
10  end;
11  
12  {Note: using properties is not strictly necessary, but is good style as it allows 
13  easier subsequent amendment.
14  
15  Now we could use a standard TCollection to hold our TInputItems but it is neater to 
16  have a descendent of this too:}
17  
18  TInputCollection = class(TCollection)
19  public
20    function AddItem(const AName: string; AKey, AParent: integer): TInputItem;
21    property InputItem[index: integer]: TInputItem read GetInputItem; default;
22  end;
23  
24  {Creating a default property like InputItem above makes coding very tidy. It allows 
25  us to do the following:}
26  
27  var
28    InputCollection: InputCollection;
29    ix: integer;
30  
31  InputCollection := TInputCollection.Create(TInputItem);
32  InputCollection.AddItem('First', 1, 0);
33  InputCollection.AddItem('Second', 2, 0);
34  InputCollection.AddItem('FirstChild', 3, 1);
35  
36  for ix := 0 to InputCollection.Count - 1 do
37    if InputCollection[ix].Parent = 0 then
38      {DoSomething};
39  
40  {The last line, because of the index property being declared default, is the same 
41  as:}
42  
43  if InputCollection.InputItem[ix].Parent = 0 then
44    {DoSomething;}
45  
46  //Without the property at all, you would code:
47  
48  if TInputItem(InputCollection.Items[ix]).Parent = 0 thenDoSomething;
49  {DoSomething;}
50  
51  //In order to support the above, the implementation of the two methods:
52  
53  function TInputCollection.AddItem(const AName: string; AKey, AParent: integer):
54    TInputItem;
55  begin
56    Result := Add as TInputItem;
57    Result.Key := AKey;
58    Result.Name := AName;
59    Result.Parent := AParent;
60  end;
61  
62  function TInputCollection.GetInputItem(index: integer): TInputItem;
63  begin
64    Result := Items[ix] as TInputItem;
65  end;
66  
67  //We can now design an overall structure of a PopulateTree procedure:
68  
69  procedure PopulateTree(tv: TTreeView);
70  var
71    ic: TInputCollection;
72  begin
73    ic := TInputCollection.Create(TInputItem);
74    try
75      LoadTreeItems(ic);
76      PopulateTreeItems(tv, nil, ic, 0);
77    finally
78      ic.Free;
79    end;
80  end;
81  
82  //LoadTreeItems can be tested via code similar to:
83  
84  procedure LoadTreeItems(ic: TInputCollection);
85  begin
86    ic.AddItem('First', 1, 0);
87    ic.AddItem('Second', 2, 0);
88    ic.AddItem('FirstChild', 3, 1);
89  end;


before replacing with your own loop through your input file. PopulateTreeItems is 
passed the treeview, the parent node and the parent id and it is a recursive 
routine.


2) Having done all the above, this part is now very easy. PopulateTreeItems 
iterates through the collection looking for items that match the passed parent id. 
For each item that matches, it adds a treenode and then calls PopulateTreeItems 
passing itself as the parent:
90  
91  procedure PopulateTreeItems(tv: TTreeView; pnode: TTreeNode; ic: TInputCollection;
92    parent: integer);
93  var
94    node: TTreeNode;
95    ix: integer;
96  begin
97    for ix := 0 to ic.Count - 1 do
98    begin
99      if ic[ix].Parent = parent then
100     begin
101       node := tv.Items.Add(pnode, ic[ix].Name);
102       PopulateTreeItems(tv, node, ic, ic[ix].Key); {recursive call}
103     end;
104   end;
105 end;


I apologise in advance if there are problems with the above code. It is completely untested. In practice, I don't do things quite like that, but populate treenodes on demand via the OnExpand event handler.

			
Vote: How useful do you find this Article/Tip?
Bad Excellent
1 2 3 4 5 6 7 8 9 10

 

Advertisement
Share this page
Advertisement
Download from Google

Copyright © Mendozi Enterprises LLC