2013-12-16 93 views
1

美好的一天!TTreeView:AlphaSort滾動到選定節點(如MakeVisible)

我有一些問題。當我爲所選節點的父節點調用AlphaSort時(由於向下滾動或向上滾動樹形視圖,選定節點此時不可見),treeview滾動到所選節點(如調用MakeVisible)。我如何禁止樹視圖確保在排序過程中可見?我試圖攔截TVM_ENSUREVISIBLE這樣

type 
    TTreeNode = class(ComCtrls.TTreeNode) 
    protected 
     procedure EnsureVisible(var Message: TMessage); message TVM_ENSUREVISIBLE; 
    end; 

type 
    TTreeView = class(ComCtrls.TTreeView) 
    protected 
     procedure EnsureVisible(var Message: TMessage); message TVM_ENSUREVISIBLE; 
    end; 

... 

{ TTreeView } 

procedure TTreeView.EnsureVisible(var Message: TMessage); 
begin 
    inherited; 
    ShowMessage('MakeVisibleFromTreeView'); 
end; 

{ TTreeNode } 

procedure TTreeNode.EnsureVisible(var Message: TMessage); 
begin 
    inherited; 
    ShowMessage('MakeVisibleFromTreeNode'); 
end; 

但在排序在滾動過程中沒有此消息的電話。只有在我手動調用MakeVisible的情況下。

+0

這就是底層控件的行爲。要想出一個適用於所有場景的完全一般的解決方案將非常困難。 –

+0

@David,您可以保存滾動條的位置,並在排序完成後恢復它,同時在排序過程中窗口將被鎖定以進行更新。 – TLama

+0

@TLama是的。但是結果可能是控件現在顯示了樹的完全不同的部分。例如,在排序之前,如果在當前可見節點下面有一個展開的節點,其中有1000個子節點,不可見。然後,在排序之後,該展開的節點在樹上向上移動,您可能會想知道如何到達樹的這一部分。 –

回答

2

您觀察到的行爲由底層樹視圖控件提供。可能沒有太多的事情可以阻止它的發生。所以,如果你想改變行爲,你需要解決這個問題。

你必須決定你真正想要的行爲。排序完成後,您希望哪些節點可見。 @TLama建議存儲滾動條位置,排序,然後恢復滾動條位置。但那可能會有令人驚訝的結果。首先,不能保證排序之前在排序之前可見的任何節點都可見。如果你正在排序的節點有孩子,那也可能會增加孩子們的獨特性。

但是,你在評論中說,被排序的節點沒有孩子。在這種情況下,我認爲@TLama建議可以滿足您的需求。有一個相當簡單的方法來實現它。您需要在排序前記住頂部項目的索引,然後在排序後將頂部項目設置爲具有該索引的項目。像這樣:

TreeView1.Items.BeginUpdate; 
try 
    TopIndex := TreeView1.TopItem.Index; 
    TreeView1.AlphaSort; // or whatever you do to perform the sort 
    TreeView1.TopItem := TreeView1.Items[TopIndex]; 
finally 
    TreeView1.Items.EndUpdate; 
end; 
+0

非常感謝! – ventik