Can some one explain me, how MultiSelectStyle
, Selected
and Selected.Count
properties works for TTreeView
in Delphi 7? I've been away Delphi coding for years and unless someone points me out, what do I miss, I see absolutely no logic behind that.
To the point. I have a routine that fills TTreeView
with contents of selected folder. It uses recurence, so each folder is represented as node with children -- it's subfolders and files. User can select multi items on a tree, because MultiSelect
is set to True
. In MultiSelectStyle
group I've set all four child properties to True
as well (maybe that was a mistake).
As a debug of my program (which works exactly opposite, I would expect) I have this code:
ShowMessage(IntToStr(tvShell.Selected.Count) + ' selected');
for i := 0 to (tvShell.Selected.Count - 1) do
begin
ShowMessage(tvShell.Selected.Item[i].Text);
end;
So I run my program and select any folder. Tree renders and I see:
Text
and with six children, as selected folder contains six subfolders and no files,Using Ctrl
and mouse, I select first (44 files) and last (9 files) tree node (children of root node) and hit the button that executes above mentioned debug code.
What do I expect? I see two items selected. Since msVisibleOnly
is set to True
among MultiSelectStyle
, I expect to have tvShell.Selected.Count
set to 2
and see three messages.
What do I get? First message says that I have... nine items selected and when I continue, I'm getting additional nine messages, showing me contents of last folder (tree children). The funniest part is that among tvShell.Selected
there are no sign of those two, that are actually selected by me! WTF?
Non-sense continues...
I repeat all these steps, but this time I'm selecting (clicking) on last folder (children) and with Ctrl
button pressed, I'm clicking on first folder (root's children). As a human I again see, that I have two items selected. When looking at this tree I visually see no difference in selection. But Delphi does.
When executing debug code, this time I'm getting information that there are fourty four items selected and I'm getting 44 additional message boxes showing me contents of first folder. Completely confused, I'm clicking +
next to first and last folder to see, if there are any items selected inside, but no (since msVisibleOnly
is set to True
).
I see, how does it work (always claiming that children of last time clicked item are all among selected items), but I don't understand it. Where is the logic behind this, if any? How this can be useful, if results from the code does not reflect the reality?
Sorry, for hard tongue, but this is complete stupidity for me. Since I don't code in Delphi (I actually hate that language for more things like that) I don't look for an enlightenment or explanation, why this works like it works (although, if someone have some spare time, I'll be more than happy to read it).
But I would truly be happy, if someone could explain me, what magic do I have to do in code and among TTreeView
properties, to get from code, what is truly selected, not the Delphi's false interpretation of reality. If I see two items selected, I want tvShell.Selected.Count
to be set to 2 and I want tvShell.Selected
contain exactly two items -- both, that I have selected. Nothing more, nothing less.
Sorry, that this question is such long, but I had to react after frustration I've got, when finding (again, after years), that Delphi is really a weird language.
Your code displays the value of
tvShell.Selected.Count
That's the number of nodes that are direct children of tvShell.Selected
. Remember that tvShell.Selected
is just a single node.
You probably meant to use
tvShell.SelectionCount
And you then display
tvShell.Selected.Item[i].Text
These are the captions of the direct children of tvShell.Selected
.
If you want to iterate through all selected nodes then you can do it like this:
for i := 0 to tvShell.SelectionCount-1 do
DoSomething(tvShell.Selections[i]);
I recommend reading the online help when you are faced with situations like this. Particularly for Delphi 7 the documentation is very clear. For Selected
the documentation states:
Specifies the selected node in the tree view.
property Selected: TTreeNode;
Description
Read Selected to access the selected node of the tree view. If there is no selected node, the value of Selected is nil.
.....
If the MultiSelect property is True and the MultiSelectStyle property includes msControlSelect, then Selected returns the last node clicked on, even if that click deselected the node. For a current selection status when MultiSelect is True, refer to the Selections property.
And then when you follow on to the documentation for Count
it says:
Indicates the number of direct descendants of a tree node.
property Count: Integer;
Description
Use Count to determine how many child nodes belong to a tree node. Count includes only immediate children, and not their descendants. Count can be useful when iterating through the children of a tree node.
In other words, the documentation tells you just the same as I have told you.