Author: Tomas Rutkauskas
Is the ItemID a unique number for a node on the tree at hand only? Apparently this
ID is not a true handle like for Windows that changes from time to time. I can run
two instances of the same treeview object and the root node always has a number
5704360 and the second node always has the 5704400. These item IDs are cast to
integers. I am trying to create an Outline editor, using a memo and a treeview and
save the data in the memo to a stream along with some sort of unique identifier in
order to be able to move nodes around without loosing a nodes assignment to a block
of memo data. I thought about adding the itemid to the front of the block of data
and remove it from the data while streaming the data back into the memo. Am I going
in the wrong direction or what?
Answer:
I tend towards maintaining my own Ids and TreeNodes in a list:
1 TMemoSource = class(TPersisent)
2 private3 FId: Integer;
4 FNode: TTreeNode;
5 FStrings: TStringList;
6 function GetStrings: TStrings;
7 procedure SetStrings(Value: TStrings);
8 public9 property Id: Integer read FId write FId;
10 property Node: TTreeNode read FNode write FNode;
11 property Strings: TStrings read GetStrings write SetStrings;
12 end;
13 14 TMemoSources = class(TList)
15 private16 FNextId: Integer; {FNextId needs to be saved/initialised on application close/ 17 run}18 function Get(Index: Integer): TMemoSource;
19 procedure Put(Index: Integer; Item: TMemoSource);
20 public21 function AddItem: TMemoSource;
22 property NextId: Integer read FNextId write FNextId;
23 property Items[Index: Integer]: TMemoSource read Get write Put;
24 end;
25 26 function TMemoSources.AddItem: TAMemoSource;
27 var28 Item: TMemoSource;
29 begin30 Item := TMemoSource.Create;
31 Inc(FNextId);
32 Item.Id := FNextId;
33 inherited Add(Item);
34 Result := Item;
35 end;
36 37 //I'll let you fill in the other class methods ...38 39 //Example of using:40 41 procedure TForm1.AddMemoToTree(ANode: TTreeNode; AMemo: TMemo);
42 var43 Ms: TMemoSource;
44 begin45 Ms := MemoSources1.AddItem;
46 Ms.Strings.Assign(AMemo.Lines);
47 Ms.Node := TreeView1.Items.AddChildObject(ANode, 'Memo' + IntToStr(Ms.Id), Ms);
48 end;
I find the biggest advantage of maintaining a list is you can hunt the list by Id or Node rather than the treeview. The list approach also lends itself to dynamically adding and deleting nodes to the treeview in the OnExpanding and OnCollapsing events remembering to set Ms.Node := nil if you delete a treenode and don't delete the corresponding memosource.