2013-08-28 56 views
2

當我用TTreeView打開窗體時,我用一些數據填充它並選擇一些節點。但我需要讓選定的節點在控制中心可見(當然可能)。我找不到如何使用標準的TTreeView組件。 任何想法?如何居中特定TreeView節點的位置?

+0

是不夠的你,以確保它通過['MakeVisible'(http://docwiki.embarcadero.com/Libraries/XE3/en/Vcl.ComCtrls.TTreeNode.MakeVisible)可見?你想要的是計算自己滾動和滾動的距離。 – TLama

+0

@TLama - 我正在使用Delphi XE3,當我選擇節點時,它變得可見,但它看起來不是很好,因爲用戶需要看到一些上下文(選定項目的下方和上方)。 –

+2

那麼,然後獲取節點邊界('DisplayRect(False)'),計算它到要居中位置的距離並滾動控件。這是我能想到的唯一方法。 – TLama

回答

3

我可以找到滾動TreeView的唯一方法是發送一個WM_VSCROLL,其值爲SB_LINEDOWN/SB_LINEUP。出於某種原因,控件似乎沒有響應滾動值SB_THUMBPOSITION,例如豐富的編輯。出於這個原因,下面的嘗試,通過發送控制一堆行滾動消息或多或少中心節點。如果它適合您的需求,請親自嘗試一下。

var 
    DR, CR: TRect; 
    ScrollPx, ScrollLines, i: Integer; 
begin 
    if Assigned(TreeView1.Selected) then begin 

    // calculate how many *pixels* should we scroll 
    DR := TreeView1.Selected.DisplayRect(False); 
    CR := TreeView1.ClientRect; 
    ScrollPx := - Round((CR.Bottom/2) - DR.Top - ((DR.Bottom - DR.Top)/2)); 

    // how many lines does it correspond to 
    ScrollLines := ScrollPx div TreeView_GetItemHeight(TreeView1.Handle); 

    // scroll that many lines 
    if ScrollLines > 0 then 
     for i := 1 to ScrollLines do 
     TreeView1.Perform(WM_VSCROLL, MakeWParam(SB_LINEDOWN, 0), 0) 
    else if ScrollLines < 0 then 
     for i := ScrollLines to -1 do 
     TreeView1.Perform(WM_VSCROLL, MakeWParam(SB_LINEUP, 0), 0); 
    end; 
+1

它的工作原理。謝謝! –

+0

我仍然想知道如何在像素上滾動任何窗口控件(滾動條)有一個明確的答案。我最多可以移動窗口的內容(通過'ScrollWindowEx'函數),但它並不是永久的。當控件失效時,窗口內容*移回*,我從來不知道如何相應地移動滾動條。也許我應該花更多的時間在它上面。 [+1] – TLama

+1

@TLama - 我從來都不知道ScrollWindow [Ex]有什麼好處。我一直認爲它並沒有真正滾動任何東西,但它是繪製自己滾動控件的偏移區域的快捷方式,繪製失效部分的工作量仍然依賴於您。它不適用於現成的控件,因爲它們只要有機會就會畫出原來的外觀。我可能是非常錯誤的..但感謝您的投票。 :) –

相關問題