我有一个所有者绘制TListBox(lbVirtualOwnerDraw),其内容得到动态更新(一秒钟内可以有多达10个更新).一次最多可以在列表框中放置300个项目.每个项目可能有大约5行文本和与之关联的图像.每当刷新一个项目时,我都必须刷新(或使其无效)TListBox,以便VCL框架调用ListBoxDrawItem.但由于所有冗余重新涂漆,这会对整体性能产生不利影响.所以我的问题是:
有没有办法只使画布的一小部分无效,其中包含一个项目或其中一个部分的图纸?(例如,包含一行文本或位图的矩形).
我们如何在Draw Item中处理这样一个选择性的无效矩形?如果可以将整数作为Refresh或invalidate的一部分传递,我可以在DrawItem中使用它来确定要刷新的内容.
有没有办法找到一个项目在TListBox上是否可见(按索引)?
提前致谢!
Ser*_*yuz 10
您可以使用InvalidateRectapi使窗口的一部分无效.要查找项目占用的区域,可以使用ItemRectListBox 的方法.例如,使第4项无效:
var
R: TRect;
begin
R := ListBox1.ItemRect(3);
InvalidateRect(ListBox1.Handle, @R, True);
end;
Run Code Online (Sandbox Code Playgroud)
(或'False'为'InvalidateRect'的'bErase',请参阅其文档).要使位图或文本无效,请在传递给InvalidateRect之前相应地修改矩形.
您无法传递索引或任何类型的用户数据来刷新或无效.在绘画例程中,您必须根据位置确定要绘制的项目,或者如果绝对必要则使用全局变量.但是你不需要它,如果你只使一个项目的一部分无效,OnDrawItem将只调用该项目.在任何情况下,不要过于担心绘制非无效项目,因为在更新区域之外不会有任何实际绘图,您将不会有任何重大的性能损失(请参阅此处的第3段).
要确定某个项目是否可见,您将从顶部的第一个可见项目开始,并将连续项目的高度添加到控件的ClientHeight.最上面的项目是TopIndex.如果项目的高度是固定的,您已经知道最多可以看到多少项目.如果不是,你需要总结它们.
| 归档时间: |
|
| 查看次数: |
1737 次 |
| 最近记录: |