2012-04-06 76 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