2012-04-06 37 views
6

我已经学会了如何使用TVirtualStringTree,并且我发现它很棒。我有一个自定义的非可视列表,名为PackedList,由另一个线程填充。我想实时显示TVirtualStringTree中的所有列表内容。因此,我在mainform上放置了一个定时器,以每500ms更新HexLog(它是TVirtualStringTree)RootNodeCount。TVirtualStringTree和垂直滚动不能正常工作

我所有的数据都出现在VirtualStringTree上,我没有任何速度问题,非常好。但垂直滚动条有一个问题。当我在控件上按Ctrl + End以跳转到列表的末尾时,它会在中间的某处。同样,当我拖动滚动条到最后,它不会结束。但是HexLog知道DataCount。为什么不跳到最后?如果我按几次Ctrl + END,它会到达最后。

里面的定时器例程,我想说HexLog跳转到代码的列表的末尾。我该如何做和如何正确处理垂直滚动条?

procedure TMainForm.StatusUpdateTimerTimer(Sender: TObject); 
begin 
    if (FirpList.ComOperationCount > 0) and (PacketList.Items.Count <> FirpList.ComOperationCount) then 
    begin 
     HexLog.RootNodeCount := PacketList.Items.Count; 
    end; 
end; 

procedure TMainForm.HexLogMeasureItem(Sender: TBaseVirtualTree; 
    TargetCanvas: TCanvas; Node: PVirtualNode; var NodeHeight: Integer); 
begin 
    if Sender.MultiLine[Node] then 
    begin 
    TargetCanvas.Font := Sender.Font; 
    NodeHeight := HexLog.ComputeNodeHeight(TargetCanvas, Node, 1, FirpList.ComOperations[Node^.Parent^.Index].DataAsHexString(FAppSettings.HexLogColumnCharWidth) + #13#10); 
    end; 
end; 

Appearance of HexLog

建议由TLama答复不能正常工作,看到图像的解释: TLama solution is not working

请参阅链接以查看详细图片说明:http://i43.tinypic.com/1445thi.png

回答

6

要跳到树的末尾,请拨打ScrollIntoView(GetLast)

要滚动到特定节点,控件需要将所有先前节点的高度相加,以确定正确的偏移量。

你的节点有不同的高度。如果您未初始化某处的节点的实际高度,则该控件将对所有未初始化的节点使用DefaultNodeHeight属性。看起来高度比树中任何实际节点高度都短,因此控件最终计算的偏移量小于预期值,并且在那里滚动而不是您想要的位置。

请确保您正在处理OnMeasureItem事件,并且您有toVariableNodeHeight选项在Options.MiscOptions中设置。如果您不这样做,那么控件将仅为每个节点使用当前分配的高度,并为任何未初始化的节点使用默认高度。

如果您手动指定NodeHeight而不是设置toVariableNodeHeight并处理OnMeasureItem,则可以在此处获得您要报告的行为。

+0

嗨,罗布,我有处理MeasureItem计算MultiLine子高度。 toVariableNodeHeight未在MiscOptions上设置。我做到了这一点,现在ScrollIntoView()正确跳转到最后。但它会略微向下滚动,并且需要大约2秒才能到达不可接受的终点:/ – 2012-04-06 14:53:10

+0

除计算所有新节点的高度外,计算最后一个节点的偏移量需要花费时间的主要因素是如果节点位置缓存无效。在'GetDisplayRect'中设置一个断点,当你调用'ScrollIntoView'时,看看你是否处于'tsUseCache'状态。当缓存有效时,树可以更快地找到节点的位置,但更改节点数会使缓存失效。工作线程需要时间来重新验证它。当我调用ScrollIntoView()时,GetDisplayRect()函数中的 – 2012-04-06 15:34:08

+0

(fStates中的tsUseCache)条件返回false。我现在应该怎么做?对于这个项目,我使用RichEdit控件,由于我遇到了速度问题,我将所有设计都改为使用VirtualStringTree。现在我再次说到:/实际上我很难理解为什么我需要计算整个消息的高度来跳到列表的末尾。我只想在数据事务处于活动状态时每隔500毫秒向用户显示最后一条消息。 – 2012-04-06 16:37:56