## clearing a treeview

Please discuss general Delphi programming topics here.

### clearing a treeview

Hi,
I have a form with a treeview and 2 buttons
On the forms OnCreate event, an XML file is loaded into the treeview
The code is timed and displayed in the statusbar1.Panels[0]
Clicking the first button clears the treeview, this code is also timed and is displayed in the statusbar1.Panels[1]
Clicking the second button reloads the XML file into the treeview
Again, the code is timed and is displayed in the statusbar1.Panels[2]

1220 verbs : 0,378 seconds
Cleared in : 13,7 seconds
1220 verbs : 0,972

Obviously, there is a few milliseconds difference each time I run the program

My question is why does it take almost 14 seconds to clear the treeview. If I just close the form by clicking the X in the top right hand corner, Delphi closes normally after freeing memory, cleaning up etc. in 1 or 2 seconds.
I don't need to clear the data in my project, I'm curious to know what delphi is doing for 14 seconds.

The code for the form OnCreate event and the reload button is the same except for the statusbar1.Panels
The clear treeview code is just
TreeView1.Items.Clear;
with the timing code.

I like your site - it has a clean and simple layout. I hope to use your MRU code in this project of mine. At the moment, I am playing around with Delphi whilst learning BDS 2006
Thanks for and help in advance but again, it is not important, I'm just curious

Code: Select all
procedure TForm4.FormCreate(Sender: TObject);var  pList: IXMLTree2xmlType;  i: integer;  aTreeNode: TTreeNode;  Freq, StartCount, StopCount: Int64;  TimingSeconds: double;begin  pList := Gettree2xml(XMLDocument1);  TreeView1.Items.BeginUpdate;  QueryPerformanceFrequency(Freq);  QueryPerformanceCounter(StartCount);  for i := 0 to pList.Count - 1 do  begin    aTreeNode := TreeView1.Items.Add(nil,pList.VMot[i].iVerb);    TreeView1.Items.AddChild(aTreeNode,pList.VMot[i].eVerb);    QueryPerformanceCounter(StopCount);    TimingSeconds := (StopCount - StartCount) / Freq;    TreeView1.Items.EndUpdate;    TreeView1.Items[0].Selected := true;    StatusBar1.Panels[0].Text := (' ' + inttostr(pList.Count - 1) + ' verbs : ' + FloatToStrF(TimingSeconds, ffGeneral, 3, 2) + ' seconds');  end;end;

Code: Select all
procedure TForm4.Button2Click(Sender: TObject);var  Freq, StartCount, StopCount: Int64;  TimingSeconds: double;begin  QueryPerformanceFrequency(Freq);  QueryPerformanceCounter(StartCount);  TreeView1.Items.Clear;  QueryPerformanceCounter(StopCount);  TimingSeconds := (StopCount - StartCount) / Freq;  StatusBar1.Panels[1].Text := (' Cleared in... ' + FloatToStrF(TimingSeconds, ffGeneral, 3, 2) + ' seconds');end;
safran
Member

Posts: 3
Joined: December 17th, 2008, 9:29 am
Location: France

### Re: clearing a treeview

Try this:
TreeView1.Items.BeginUpdate;
TreeView1.Items.Clear;
TreeView1.Items.EndUpdate;

Any difference?
w2m
w2m
Senior Member

Posts: 76
Joined: March 8th, 2003, 7:11 pm
Location: New York, USA

### Re: clearing a treeview

Hi,
Thank you w2m for the quick response. When I googled "beginupdate delphi", the first response I got was:

If you use a Delphi component like a ListBox, Memo, TreeList, ListView,... and you add or modify a lot of items (lines, nodes,...), the component's performance becomes very slow. This is due to the fact that after each change, it is redrawn on the screen. Thus, modifying 10000 items of a ListBox causes 10000 redraws, and that takes from several seconds to several minutes, depending on the computer's speed and the complexity of the process.

OK So I added a memo and button to the form with the following code + the timing code
Code: Select all
  Memo1.Lines.BeginUpdate;  for i := 1 to 5000 do    Memo1.Lines.Add('abcd');  Memo1.Lines.EndUpdate;

The timings were 0,707 seconds with the beginupdate
and 5,78 seconds without the beginupdate

So the code works but not for the original treeview. If I figure out what I'm doing wrong I'll let you know

Thanks again
safran
Member

Posts: 3
Joined: December 17th, 2008, 9:29 am
Location: France

### Re: clearing a treeview

1. When you call TreeView.Items.Clear, Delphi internally calls BeginUpdate and EndUpdate of the control.
2. Delphi only sends a windows message to the TreeView to clear its nodes. It's Windows that clears the nodes.
3. Delphi receives notification from Windows about deleted nodes, and then deletes the node object.
Therefore, you can only do a few things to speed up node removal, but just a few milliseconds:

1. Use a faster memory manager like FastMM to speed up deleting the node object.
2. Remove OnDeletion event handler. If you have attached data to each node, you must release their allocated memory before clearing nodes.
3. Before deleting, set SelectedNode to a the first root node. After deleting the selected node, TreeView tries to select another node. Let that node be the last one.
Even releasing the TreeView and recreating a clone of the old one does not solve the problem. To check it out by yourself, declare a MemoryStream in your form, and use the following code:

Code: Select all
procedure TForm1.FormCreate(Sender: TObject);begin  Stream := TMemoryStream.Create;  Stream.WriteComponent(MyTreeView);end;procedure TForm1.FormDestroy(Sender: TObject);begin  Stream.Free;end;procedure TForm1.ClearTreeView;var  NewTreeView: TTreeView;begin  NewTreeView := TTreeView.Create(TreeView1.Owner);  NewTreeView.BoundsRect := TreeView1.BoundsRect; // to prevent flickering  NewTreeView.Parent := TreeView1.Parent;  TreeView1.Free;  Stream.Position := 0;  Stream.ReadComponent(NewTreeView);  TreeView1 := NewTreeView;end;

Seems you have to use a third party TreeView control or use TreeView in virtual mode.
Kambiz

Kambiz

Posts: 2428
Joined: March 7th, 2003, 7:10 pm

### Re: clearing a treeview

Thank you Kambiz for your response.
safran
Member

Posts: 3
Joined: December 17th, 2008, 9:29 am
Location: France