我正在寻找一种基于过滤规则过滤 VirtualStringTree 中节点的快速方法,尤其是在过滤规则更改时。VST 中内置了一种筛选机制,您可以在其中定义是否筛选出节点。
我现在的解决方案是在节点初始化时确定节点是否已被过滤掉。当筛选器更改时,我会循环访问所有已初始化的节点,并根据需要更改筛选器状态。
问题是初始化的节点越多,遍历它们所需的时间就越长。窗口外有许多节点现在不需要过滤器信息(虚拟范式(。
问题是,是否有类似于过滤器失效系统/过滤器事件/其他解决方案之类的东西,只接触真正需要"过滤器已更改"信息的节点?
procedure TfrmMain.vstInitNode(Sender: TBaseVirtualTree; ParentNode,
Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
var
Data: PMyDataType;
begin
Data := Sender.GetNodeData(Node);
Data^ := GetData(Node.Index);
if IsNodeFiltered(Data^) then Include(InitialStates, ivsFiltered);
end;
procedure TfrmMain.OnFilterRuleChanged();
var
Node: PVirtualNode;
Data: PMyDataType;
begin
vst.BeginUpdate;
try
for Node in vst.InitializedNodes do
begin
Data := vst.GetNodeData(Node);
vst.IsFiltered[Node] := IsNodeFiltered(Data^);
end;
finally
vst.EndUpdate;
end;
end;
没有"只接触真正需要'过滤器已更改'信息的节点"的失效系统。为了显示所有节点的正确滚动条和正确的可展开状态,您需要查看所有已初始化的节点是否仍要显示。了解过滤器的工作原理后,您可以优化 for 循环中的内容并跳过某些节点。您也可以考虑使用 vst.VisibleNodes
而不是 InitializedNodes
,但随后还需要在扩展节点时进行过滤。