Author: Jonas Bilinkevicius
I'm trying to synchronize different nodes in a TTreeView with different text
displayed in a TMemo control.
Answer:
Lets assume you want to store the memo text into TStringList instances and store
the stringlist reference into the node.data property. The first order of the day is
to create the stringlists. You do that when you create the nodes, that is the
logical place to do it. So after you have added a node you do a
1 2 node.Data := TStringlist.Create;
The stringlist is initially empty, of course. So if you have some data to load into
the node you can load it into the stringlist with a statement like
3 4 TStringlist(node.data).Text := SomeStringValue;
The act of moving the text to the memo and back is now a simple assignment, no
stringlists get created for that since we already have them. The main problem is to
get aware when the user moves to a new node, so the old (perhaps edited) node can
be updated from the memo. This seems to be another problem that is giving you
grief. The solution is to track the *last* selected node, the one whos content is
currently in the memo. Add a field
5 6 FLastNode: TTreeNode;
to your form (private section). This field starts out as Nil (no node active).
7 8 procedure TForm1.tv_eg5Change(Sender: TObject; Node: TTreeNode);
9 begin10 if Node.Selected and (FLastNode <> Node) then11 begin12 if Assigned(FLastNode) then13 TStringlist(FLastNode.Data).Assign(memo1.lines);
14 Memo1.Lines.Assign(TStringlist(Node.Data));
15 FLastNode := Node;
16 end;
17 end;
18 19 procedure TForm1.Memo1Exit(Sender: TObject);
20 begin21 if assigned(FLastnode) then22 TStringlist(FLastNode.Data).Assign(memo1.lines);
23 end;
You have to check whether the memos Onexit event happens before or after the
treeviews OnChange event if you have focus on the memo and click on an item in the
treeview. If it happens after the OnChange event the Onexit handler needs to be
modified to look like
24 procedure TForm1.Memo1Exit(Sender: TObject);
25 begin26 if assigned(FLastnode) andnot treeview1.focused then27 TStringlist(FLastNode.Data).Assign(memo1.lines);
28 end;
Otherwise you will assign the memos content just back from the node the OnChange
handler just loaded it from.
A final thing you have to do is free the stringlist items attached to the treeview
before the form is destroyed. If you don't use drag & dock with the treeview or the
form it is on you could use the OnDeletion event of the treeview for this, doing a
29 30 TObject(node.data).Free;
in the handler. If drag & dock is involved this is not a good idea since the event fires each time the treeview or its parent changes from undocked to docked status and back. In this case the forms OnCloseQuery or OnClose event may be suitable. There you iterate over the treeviews nodes and do the free on each as above.