Virtual Treeview使用要點

Virtual Treeview是一套Delphi下優秀的VCL控件,代碼質量高,使用靈活、功能強大、性能很是好,能夠用於表達Treeview和表格類數據。它的代碼如今託管在google code上。css

這套控件使用了好久了,很是滿意其表現,以前一直使用V4版,如今V5正式發佈了,新版花了幾年時間進行重構, 代碼結構更加合理,去除了老版大量的小缺陷,不少功能進行了從新設計,參與維護的人也更多了。性能

Virtual Treeview的設計思路與官方的Treeview徹底不同,VT是基於高性能和更豐富的表現而開發的,在上手方面比Treeview要慢一些,但一旦上手,就會發現很是好用。ui

在使用VT以前,就應該設計好以什麼方式展現數據,每一個節點應該有些什麼屬性。在構思好後,就能夠按如下步驟來實現VT的使用了。google

一、節點數據

在實際使用Virtual Treeview以前,應該先設計好一個節點數據的結構體,用於方便每一個節點的展現。spa

好比一個典型的設計以下:設計

PTreeData = ^TTreeData; TTreeData = record Level: integer; // 節點級別:0根;1節點;2參數 NodeType: integer; // 節點類型 Id: Integer; // 數據id Caption: String; // 節點標題 obj : TObject; // 節點對應的對象或空 end; 

其中Caption用於控制節點顯示,Id用於方便節點對應數據的快速定位,obj用於把節點與相關的對象關聯在一塊兒,其它數據也是用於方便進行數據處理的。指針

二、列的處理

通常狀況下,若是是隻當成普通Treeview,無需考慮列(Column)的處理,直接使用便可。若是一行有多列數據須要顯示,則得先在屬性Header-Columns中增長所需的列,並設置合適的列寬。缺省列(Column)設置爲空,列索引(TColumnIndex)應該爲-1,在設置了列後,第一列的列索引爲0,第二列的列索引爲1。code

 

三、第一個節點

在樹中的全部節點中,只有根節點的父節點爲空(nil)。建立根節點的示例代碼以下:orm

var Data : PTreeData; Node: PVirtualNode; RootNode: PVirtualNode; vst.Clear; // 清除全部節點 vst.NodeDataSize := Sizeof(TTreeData); // 設置節點數據大小 RootNode := vst.AddChild(nil); // 增長一個根節點 vst.ValidateNode(RootNode, false); Data := vst.GetNodeData(RootNode); // 獲取節點數據 Data.Caption := '根節點1'; // 設置將要顯示在節點的文本信息 

四、多級節點

建立徹底根節點後,就能夠在根節點後增長各級子節點了。對象

Node := vst.AddChild(RootNode); // 增長一級子節點 data := vst.GetNodeData(Node); // 獲取節點數據 data.Level := vst.GetNodeLevel(Node); // 設置節點級別,方便後繼處理 Node := vst.AddChild(Node); // 增長二級子節點 data := vst.GetNodeData(Node); data.Level := vst.GetNodeLevel(Node); Node := vst.AddChild(RootNode); // 再增長一個一級子節點 data := vst.GetNodeData(Node); data.Level := vst.GetNodeLevel(Node); // 固然這裏能夠批量產生多個子節點,好比 // for i:=0 to 99 do // begin Node := vst.addchild(rootNode); ... end; vst.FullExpand(RootNode); // 把根節點下的全部子節點打開 

上面只是簡單示例,完整示例中須要把節點數據都設置完整。

這裏還有一種方式進行更高速的建立子節點,好比:

vst.ChildCount[RootNode] := 100; 

這樣,就能夠一下給根節點設置100個一級子節點。固然,這些節點的數據都仍是缺省狀態,咱們能夠在適當的時候和適當的位置再進行設置。

若是咱們須要一次插入多個節點,爲了提升顯示效率,咱們應該在插入前調用BeginUpdate,在插入完成後再調用EndUpdate。

五、顯示節點內容

運行後,能夠發現樹的確出來了,但全部節點顯示的都是彷佛"Node"字樣的東西,怎麼樣把咱們須要顯示的內容顯示出來?

咱們須要設置Virtual Treeview的GetText事件,VT在顯示節點信息時會調用GetText來獲取要顯示的內容。咱們能夠增長相似下面的代碼:

procedure TfrmMain.vstGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string); var Data : PTreeData; begin CellText := ''; Data := vst.GetNodeData(Node); if not Assigned(Data) then exit; Case Data.Level of 0: begin CellText := Data.Caption; end; 1: begin CellText := format('一級子節點',[]); end; 2: begin CellText := format('二級子節點',[]); end; end; end; 

固然,實際代碼要複雜的多。並且這個代碼並無處理多列的狀況,若是有多列就得針對各列再加一級case語句就能夠了。也就是說相似這樣的代碼,假設咱們設置了一個節點有三列:

procedure TfrmMain.vstGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string); var Data : PTreeData; begin CellText := ''; Data := vst.GetNodeData(Node); if not Assigned(Data) then exit; Case Column of 0: // 第一列的處理 begin Case Data.Level of 0: begin CellText := Data.Caption; end; 1: begin CellText := format('一級子節點',[]); end; 2: begin CellText := format('二級子節點',[]); end; end; end; 1: // 第二列的處理 begin // 通常是取Data中obj對象,再取其中的數據用於處理顯示 end; 2: // 第三列的處理 begin // 通常是取Data中obj對象,再取其中的數據用於處理顯示 end; end; end; 

也就是說vst各節點的內容,其實都是經過代碼來控制並設置的。不管是Treeview形式仍是表格形式或二者綜合體,數據的顯示都是這麼處理的。

五、節點圖標

常常咱們須要在每一個節點前加個小圖標,可用於表達這個節點的狀態、類型或純美觀。Virtual Treeview顯示圖標同樣也是要與TImageList配合使用的。咱們須要先在一個ImageList中加載上合適的全部圖標,而後在GetImageIndex事件中進行判斷處理每一個節點應該使用的圖標的索引來加載ImageList中的圖標。

好比:

procedure TfrmMain.vstGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean; var ImageIndex: Integer); var Data : PTreeData; begin Data := vst.GetNodeData(Node); if not Assigned(Data) then exit; Case Data.Level of 0: begin ImageIndex := 2; end; 1: begin ImageIndex := 0; end; 2: begin ImageIndex := 0; end; end; end; 

六、節點數據空間的清理

在Virutal Treeview組件釋放時,咱們應該同時清理掉每一個節點對應的數據空間。咱們應該在FreeNode事件中寫上如下相似的代碼來完成這個工做:

procedure TfrmMain.vstFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode); var Data : PTreeData; begin Data := vst.GetNodeData(Node); if Assigned(Data) then begin Data.Caption := ''; // String must be cleaned manual, otherwise there is memory leak // 節點數據記錄中對應的數據對象,不必定得在這釋放,能夠在其它地方統一處理 //FreeAndNil(Data.obj);
end; end;

節點數據空間不須要咱們釋放,在前面對vst初始化時寫過這麼一句代碼:

vst.NodeDataSize := Sizeof(TTreeData); // 設置節點數據大小 

這裏就是初始化節點數據記錄空間的,這個空間會被vst自動釋放。但這個記錄體中的相似字符串或指針所指向的內存空間或對像是不會被自動釋放的。因此,這裏咱們把Data.Caption字符串清空,以免內存泄漏。

相關文章
相關標籤/搜索