-, OnChecking - . OnChecked. OnChecking : " node ?"? , . OnChecked .
-, . toAutoTristateTracking, . ( , . , "undefined".)
, , . node , node , node. , , - , . . , , . , .
. OnChecked, , , . , , , .
procedure PropagateCheckState(Tree: TVirtualStringTree; Node: PVirtualNode);
var
Data: PNodeData;
TargetID: string;
Parent: PVirtualNode;
FoundOne: Boolean;
begin
Data := Tree.GetNodeData(Node);
TargetID := Data.SkypeID;
Parent := Tree.GetFirst;
while Assigned(Parent) do begin
// Assume no user appears twice in the same category
if Parent <> Tree.NodeParent[Node] then begin
FoundOne := False;
Child := Tree.GetFirstChild(Parent);
while Assigned(Child) and not FoundOne do begin
Data := Tree.GetNodeData(Child);
if Data.SkypeID = TargetID then begin
// Found a duplicate. Sync it with Node.
Tree.CheckState[Child] := Tree.CheckState[Node];
FoundOne := True;
end;
Child := Tree.GetNextSibling(Child);
end;
end;
Parent := Tree.GetNextSibling(Parent);
end;
end;
procedure TSkypeListEventHandler.vtSkypeChecked(Sender: TBaseVirtualTree; Node: PVirtualNode);
var
CheckedEvent: TVTChangeEvent;
begin
if Sender.GetNodeLevel(Node) = 0 then
exit; // The tree cascades changes automatically
Assert(Sender.GetNodeLevel(Node) = 1, 'Unexpected node level');
// We'll be accessing members that are protected in TBaseVirtualTree, but
// they're public in TVirtualStringTree, so make sure we're still operating
// on the same tree.
Assert(Sender = vtSkype);
CheckedEvent := vtSkype.OnChecked;
vtSkype.OnChecked := nil;
try
PropagateCheckState(vtSkype, Node);
finally
vtSkype.OnChecked := CheckedEvent;
end;
end;
, , :
procedure PropagateCheckState(Tree: TVirtualStringTree; Node: PVirtualNode);
var
Data: PNodeData;
i: Integer;
begin
Data := Tree.GetNodeData(Node);
for i := 0 to Pred(Data.User.Nodes.Count) do
Tree.CheckState[Data.User.Nodes[i]] := Tree.CheckState[Node];
end;
( , ), , , . Delphi, TDictionary<string, TList<PVirtualNode>>. PropagateCheckState :
uses Generics.Collections;
var
UserNodes: TDictionary<string, TList<PVirtualNode>>;
procedure PropagateCheckState(Tree: TVirtualStringTree; Node: PVirtualNode);
var
Data: PNodeData;
Nodes: TList<PVirtualNode>;
i: Integer;
begin
Data := Tree.GetNodeData(Node);
if not UserNodes.TryGetValue(Data.SkypeID, Nodes) then
exit;
for i := 0 to Pred(Nodes.Count) do
Tree.CheckState[Nodes[i]] := Tree.CheckState[Node];
end;
UserNodes , .