CodedK
asked on
TreeView items clear..
Hi.
I have a TreeView with several items. Some of them added dynamically.
In case something changes i'd like to add a refresh option and recalculate everything.
BUT i dont want to clear all the items ... Just the ones that were added dynamically.
How can i do that ?
Example:
~-~-~-~-~-~-~-~-~-~-~-~-~- ~-
A (should stay here)
|
A1 (Should stay here)
|
value (Should go)
B (should stay here)
|
B1 (Should go)
|
B2 (Should go)
|
B3 (Should go)
|
B4 (Should go)
~-~-~-~-~-~-~-~-~-~-~-~-~- ~-
Thanks in advance.
I have a TreeView with several items. Some of them added dynamically.
In case something changes i'd like to add a refresh option and recalculate everything.
BUT i dont want to clear all the items ... Just the ones that were added dynamically.
How can i do that ?
Example:
~-~-~-~-~-~-~-~-~-~-~-~-~-
A (should stay here)
|
A1 (Should stay here)
|
value (Should go)
B (should stay here)
|
B1 (Should go)
|
B2 (Should go)
|
B3 (Should go)
|
B4 (Should go)
~-~-~-~-~-~-~-~-~-~-~-~-~-
Thanks in advance.
ASKER
I thought that too but i didnt know if treeview has tags like popup menu.
I'll try that :)
(I'll keep this open till i finish)
I'll try that :)
(I'll keep this open till i finish)
ASKER
:/
I'm using russells proc to add the childs and i cant insert a tag property in the function !
I'm using russells proc to add the childs and i cant insert a tag property in the function !
I just checked. it doesn't. sorry.
but you can use the Data property (pointer) if you don't use it for something else. you can set it to treeview instance (which is always defined) and at refresh free only those that are not nil
but you can use the Data property (pointer) if you don't use it for something else. you can set it to treeview instance (which is always defined) and at refresh free only those that are not nil
ASKER
Ok...
After this command :
For 0 to the end of values of i array do
TreeView1.Items.AddChild(I temByPath( TreeView1, 'Sections\My Computer'), s[i]);
HERE... how can i tag the existing just created child ?
After this command :
For 0 to the end of values of i array do
TreeView1.Items.AddChild(I
HERE... how can i tag the existing just created child ?
can you post that code? or link to the question having the code.
ASKER
Yes ...
//------------------------ ---------- -|
// Add values to node by caption |
//------------------------ ---------- -|
function GetPathString(var Str: PChar): String;
var lpszScan: PChar;
begin
// Check passed string
if (Str = nil) or (Str^ = #0) then
// Empty string
SetLength(result, 0)
else
begin
// Scan for path seperator
lpszScan:=StrScan(Str, '\');
// Check sep char
if Assigned(lpszScan) then
begin
// Get path string
SetString(result, Str, lpszScan-Str);
// Set to sep char position
Str:=lpszScan;
// Push next
Inc(Str);
end
else
begin
// Return whole string
SetString(result, Str, StrLen(Str));
// Set to end of string
Str:=StrEnd(Str);
end;
end;
end;
//------------------------ ---------- -|
// Add values to node by caption |
//------------------------ ---------- -|
function ItemByPath(Tree: TTreeView; Path: String): TTreeNode;
var tnChild: TTreeNode;
lpszPath: PChar;
szPath: String;
begin
// Check path and tree item count
if (Length(Path) = 0) or (Tree.Items.Count = 0) then
// No item to return
result:=nil
else
begin
// Cast path
lpszPath:=Pointer(Path);
// Check against root
if (CompareText(GetPathString (lpszPath) , Tree.Items[0].Text) = 0) then
begin
// Get root item
result:=Tree.Items[0];
// While path is not null and node has children
while (lpszPath^ > #0) and result.HasChildren do
begin
// Get next item path
szPath:=GetPathString(lpsz Path);
// Get first child
tnChild:=result.getFirstCh ild;
// Walk the children
while Assigned(tnChild) do
begin
// Check text, break if found
if (CompareText(szPath, tnChild.Text) = 0) then break;
// Next child
tnChild:=tnChild.getNextSi bling;
end;
// Break if no child
if (tnChild = nil) then break;
// Update result
result:=tnChild;
end;
end;
end;
end;
//------------------------
// Add values to node by caption |
//------------------------
function GetPathString(var Str: PChar): String;
var lpszScan: PChar;
begin
// Check passed string
if (Str = nil) or (Str^ = #0) then
// Empty string
SetLength(result, 0)
else
begin
// Scan for path seperator
lpszScan:=StrScan(Str, '\');
// Check sep char
if Assigned(lpszScan) then
begin
// Get path string
SetString(result, Str, lpszScan-Str);
// Set to sep char position
Str:=lpszScan;
// Push next
Inc(Str);
end
else
begin
// Return whole string
SetString(result, Str, StrLen(Str));
// Set to end of string
Str:=StrEnd(Str);
end;
end;
end;
//------------------------
// Add values to node by caption |
//------------------------
function ItemByPath(Tree: TTreeView; Path: String): TTreeNode;
var tnChild: TTreeNode;
lpszPath: PChar;
szPath: String;
begin
// Check path and tree item count
if (Length(Path) = 0) or (Tree.Items.Count = 0) then
// No item to return
result:=nil
else
begin
// Cast path
lpszPath:=Pointer(Path);
// Check against root
if (CompareText(GetPathString
begin
// Get root item
result:=Tree.Items[0];
// While path is not null and node has children
while (lpszPath^ > #0) and result.HasChildren do
begin
// Get next item path
szPath:=GetPathString(lpsz
// Get first child
tnChild:=result.getFirstCh
// Walk the children
while Assigned(tnChild) do
begin
// Check text, break if found
if (CompareText(szPath, tnChild.Text) = 0) then break;
// Next child
tnChild:=tnChild.getNextSi
end;
// Break if no child
if (tnChild = nil) then break;
// Update result
result:=tnChild;
end;
end;
end;
end;
like this:
var t:ttreenode;
begin
t:=TreeView1.Items.AddChil d(ItemByPa th(TreeVie w1, 'Sections\My Computer'), s[i]);
t.data:=TreeView1;
...
var t:ttreenode;
begin
t:=TreeView1.Items.AddChil
t.data:=TreeView1;
...
ASKER
I can understand
t:=TreeView1.Items.AddChil d(ItemByPa th(TreeVie w1, 'Sections\My Computer'), s[i]);
this will mark the current (i) child...
but "t.data:=TreeView1" ?
and afterwards how can i use this in a for statement to clen the tree ?
t:=TreeView1.Items.AddChil
this will mark the current (i) child...
but "t.data:=TreeView1" ?
and afterwards how can i use this in a for statement to clen the tree ?
"t.data:=TreeView1" can be anything. you set the data property to something that is NOT nil.
then, you iterate through the items:
var i:integer;
begin
i:=1;
while i<=TreeView1.items.count do
begin
if TreeView1.Items.Item[i-1]. Data<>nil then
TreeView1.Items.Item[i-1]. Delete else
inc(i);
end;
then, you iterate through the items:
var i:integer;
begin
i:=1;
while i<=TreeView1.items.count do
begin
if TreeView1.Items.Item[i-1].
TreeView1.Items.Item[i-1].
inc(i);
end;
ASKER
:O
This keeps everything there ! Nothing goes.
Since all of the created nodes are childs, we tag them we something and try to delete everything thats nil
but nothing is nil except the parent nodes (i want to keep) and they cant be deleted since childs stay...
This keeps everything there ! Nothing goes.
Since all of the created nodes are childs, we tag them we something and try to delete everything thats nil
but nothing is nil except the parent nodes (i want to keep) and they cant be deleted since childs stay...
ASKER
Sorry... we try to delete everything thats NOT nil... but they dont go !
that is because you didn't set the data property. I made a small test example and it worked like a charm.
make sure that you have added code to change the data property of teh dinamically added nodes to something that is not nil (treeview1 is not nil for sure that is why I used it)
make sure that you have added code to change the data property of teh dinamically added nodes to something that is not nil (treeview1 is not nil for sure that is why I used it)
ASKER
Of course i did ... :)
I'll recheck...
I'll recheck...
ASKER
Ok in every proc that i add a child i added these 2 lines :
~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~
TreeView1.Items.AddChild(I temByPath( TreeView1, 'Sections\My Computer'), s[i]);
---> t:=TreeView1.Items.AddChil d(ItemByPa th(TreeVie w1, 'Sections\My Computer'), s[i]);
----> t.data:=TreeView1;
~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~
TreeView1.Items.AddChild(I temByPath( TreeView1, 'Sections\hard\My Floppy'), s[i]);
---> t:=TreeView1.Items.AddChil d(ItemByPa th(TreeVie w1, 'Sections\hard\My Floppy'), s[i]);
----> t.data:=TreeView1;
~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~
TreeView1.Items.AddChild(I temByPath( TreeView1, 'Sections\My HD'), s[i]);
---> t:=TreeView1.Items.AddChil d(ItemByPa th(TreeVie w1, 'Sections\My HD'), s[i]);
----> t.data:=TreeView1;
~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~
Now i have a refresh label (OnClick):
Memo1.Clear;
Memo2.Clear;
i:=1;
while i<=TreeView1.items.count do
begin
if TreeView1.Items.Item[i-1]. Data<>nil then
TreeView1.Items.Item[i-1]. Delete else
inc(i);
end;
~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~
But nothing works !!!
~~~~~~~~~~~~~~~~~~~~~~~~~~
TreeView1.Items.AddChild(I
---> t:=TreeView1.Items.AddChil
----> t.data:=TreeView1;
~~~~~~~~~~~~~~~~~~~~~~~~~~
TreeView1.Items.AddChild(I
---> t:=TreeView1.Items.AddChil
----> t.data:=TreeView1;
~~~~~~~~~~~~~~~~~~~~~~~~~~
TreeView1.Items.AddChild(I
---> t:=TreeView1.Items.AddChil
----> t.data:=TreeView1;
~~~~~~~~~~~~~~~~~~~~~~~~~~
Now i have a refresh label (OnClick):
Memo1.Clear;
Memo2.Clear;
i:=1;
while i<=TreeView1.items.count do
begin
if TreeView1.Items.Item[i-1].
TreeView1.Items.Item[i-1].
inc(i);
end;
~~~~~~~~~~~~~~~~~~~~~~~~~~
But nothing works !!!
better just post the entire code or make a separate small app that reproduces the issue. I cannot see where the problem is
ASKER
I think that the while statement should have the t variable not the
TreeView1.Items.Item[i-1]. Data
but something like
t.items.data
Is this the problem ?
TreeView1.Items.Item[i-1].
but something like
t.items.data
Is this the problem ?
ASKER
I'll try to create a small app with a portion of the code ...
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
It works Ciuly...
The error was obvious :P (NOT)
This was what i did :
TreeView1.Items.AddChild(I temByPath( TreeView1, 'Sections\My HD'), s[i]);
---> t:=TreeView1.Items.AddChil d(ItemByPa th(TreeVie w1, 'Sections\My HD'), s[i]);
----> t.data:=TreeView1;
This is what i should do :
//////// TreeView1.Items.AddChild(I temByPath( TreeView1, 'Sections\My HD'), s[i]); <---- Obsolete
---> t:=TreeView1.Items.AddChil d(ItemByPa th(TreeVie w1, 'Sections\My HD'), s[i]);
----> t.data:=TreeView1;
So thank you again and again :) :) :)
The error was obvious :P (NOT)
This was what i did :
TreeView1.Items.AddChild(I
---> t:=TreeView1.Items.AddChil
----> t.data:=TreeView1;
This is what i should do :
//////// TreeView1.Items.AddChild(I
---> t:=TreeView1.Items.AddChil
----> t.data:=TreeView1;
So thank you again and again :) :) :)
easiest way Ii can thing of:
when creating dinamically, set the TAG property to a non-zero value. when doing the refresh, iterate through the imtems and only remove the ones that have this tag set. :)
Cheers!