我正在使用Delphi XE3和Virtual TreeView。
我想使用Virtual TreeView来实现一棵树,当单击“开始”按钮时,该程序将递归搜索驱动器下的所有文件和文件夹,然后将它们一个一个地添加到树中,就像Windows资源管理器一样。此外,应该使用一个静态文本,像这样一个数字,指示文件夹下文件和子文件夹的数量:
VirtualTreeView - different color of text in the same node
在实施过程中,我有时发现号码未正确更新。
因此,我认为,只要文件/子文件夹的数量发生更改,就可以通过以下方式刷新节点:
调用tvItems.Change(PNode)来更新节点。
调用tvItems.InvalidateNode(PNode)。
调用tvItems.RepaintNode(PNode)。
调用tvItems.UpdateAction。
但是,1是无法调用的受保护方法。 2和3都可以,但是不知道哪个更新更好。 4没有记录,也不知道如何称呼它。
基本思想是,如果幕后的事物发生变化,则需要对树进行重新粉刷。这意味着树下次绘制自身时,将使用新的基础值。
如果您的树坐在屏幕上:
您可以简单地致电:
tvItems.Invalidate;
这将告诉Windows entire树现在为“ invalid”,需要重新绘制。我可以代表这个“ invalid”区域,该区域将在树下次绘制自身时进行更新:
这很好,正确,并且可以正常运行。
很多时候,强制entire树重新绘制自身的[[all完全合理。
但是也可以开始进行优化。如果您知道Windows控件的仅某个区域是“ invalid”,则可以使该部分无效。
要执行此操作的Windows功能是InvalidateRect:InvalidateRect(tvItems.Handle, Rect(13, 18, 30, 38), True);
这将使在13,18处的30x38正方形无效:函数:事实上,所有
TWinControl.Invalidate
所做的只是转过头并调用WindowsInvalidateRect
//true means to also trigger an erase of the background
InvalidateRect(Self.Handle, Self.BoundsRect, True);
使这样一个奇怪的矩形无效可能没有太多用处。但是您可能会想像其他要失效的矩形。已经为您提供了一个方便的方法来invalidate节点:无效节点
Windows无法实现,但是您的控件代表一棵树,以及树和节点。有时候您可能想取消
“ node”:
的矩形而不是您必须弄清楚节点的坐标和大小,
TVirtualTree
function InvalidateNode(Node: PVirtualNode): TRect; virtual;
// Initiates repaint of the given node and returns the just invalidated rectangle.
so:
tvItems.InvalidateNode(someNode);
它还提供了使节点及其所有子节点]无效的方法:
procedure TBaseVirtualTree.InvalidateChildren(Node: PVirtualNode; Recursive: Boolean);
// Invalidates Node and its immediate children.
// If Recursive is True then all grandchildren are invalidated as well.
// The node itself is initialized if necessary and its child nodes are created (and initialized too if
// Recursive is True).
这在您的树个孩子时很有用:有
您可以使父节点和现在需要使用新编号更新的所有子节点失效:
tvItems.InvalidateChildren(someNode, True);
和其他辅助方法
InvalidateToBottom(Node: PVirtualNode);
从给定节点处开始重新绘制工作区。如果此节点不可见或尚未初始化,则什么都不会发生。TBaseVirtualTree.InvalidateColumn(Column: TColumnIndex);
使列的客户区部分无效。无效
屏幕上的像素现在为这将在下一次要求树进行自我绘制时发生。 Windows是基于消息的。在您的应用程序运行时,它会处理消息,包括无效
,必须重新粉刷
WM_PAINT
消息。当VirtualTree
收到WM_PAINT
消息时,它会绘制要求重新绘制的部分。
“ idle”
。如果您坐在一个繁忙的循环中,请不要让代码退出:procedure TForm1.Button1Click(Sender: TObject);
begin
while (true) do
begin
tvItems.Invalidate;
Sleep(100);
end;
end;
循环永远不会结束,树也永远不会有机会绘制自身。 Delphi的可怕重绘技巧实际上
forces]要绘制的控件。假装是Windows要求控件自己绘制的Windows
WM_PAINT
消息-它也只是进行绘制。procedure TForm1.Button1Click(Sender: TObject);
begin
while (true) do
begin
tvItems.Repaint; //force the control to repaint itself
Sleep(100);
end;
end;
这是一个丑陋的hack,因为:
WM_PAINT
消息,并照常进行绘制。