TTreeView是VCL中提供的樹列表控件,樹的每個節點是一個TTreeNode類,TTreeNode組件的屬性和方法可以參考Borland提供的幫助(雖然不如MSDN全面,但有總比沒有強)。實際應用中我們可能需要禁用某個節點(界面上反應的效果是:節點字體呈灰色顯示,節點無法選中等)。但是VCL沒有提供Node->Disable();或Node->Enable=false;這樣的功能,我們只好自己動手實現了。首先我們需要為每個節點設定一個標志,用來標識此節點是否可用,標識方法有很多,比如判斷節點的文本(Text),節點的絕對索引值(AbsoluteIndex),節點的索引(Index)加縮進(Indent)等,在本例中我們用節點的Data屬性作標識(一個void *型數據,其實可以存放N多東西)。如果在你的應用中恰好用了Data屬性,就另外想個用來作標志的方法吧。:)
我們寫一個自定義函數,用來啟用/禁用一個節點:
//---------------------------------------------------------------------------
//函數功能:改變指定節點的啟用/禁用狀態
// bEnable:啟用:true;禁用:false
// pNode:要改變狀態的節點
void__fastcallCrnEnableTreeNode(boolbEnable,TTreeNode*pNode)
{
//設定規則,如果節點允許使用,Node的Data存放0(默認就是0),
//如果禁用,Data存放0xFFFF
pNode->Data=bEnable?NULL:(void*)0xFFFF;
//標志改變後重繪一下TreeView
// 本文轉自 C++Builder 研究 - http://www.ccrun.com/article.asp?i=1015&d=r2tf61
pNode->TreeView->Invalidate();
}
然後考慮如何達到禁用節點的效果,前面說了,我們只需實現這兩個效果:
1.節點字體呈灰色顯示
2.節點無法選中
節點字體呈灰色顯示可以通過TreeView的OnCustomDrawItem事件中的自繪實現,在設計時狀態,選中TreeView,Events選項卡雙擊OnCustomDrawItem事件,添加以下代碼:
//---------------------------------------------------------------------------
void__fastcallTForm1::TreeView1CustomDrawItem(TCustomTreeView*Sender,
TTreeNode*Node,TCustomDrawStateState,bool&DefaultDraw)
{
//判斷當前繪制節點是否被禁用
// 63 63 72 75 6E 2E 63 6F 6D
if(int(Node->Data)==0xFFFF)
{
//如果節點被禁用則用灰色字體顯示,默認為黑色
Sender->Canvas->Font->Color=clGray;
}
}
節點無法選中則可以通過TreeView的Changing事件來處理,在設計時狀態,選中TreeView,Events選項卡雙擊OnChanging事件,添加以下代碼:
//---------------------------------------------------------------------------
void__fastcallTForm1::TreeView1Changing(TObject*Sender,TTreeNode*Node,
bool&AllowChange)
{
//欲選中這個節點時,判斷如果當前節點被禁用則禁止改變原節點的選擇狀態
AllowChange=(int(Node->Data)!=0xFFFF);
}
有以上的實現,效果基本就出來了:
測試代碼:
//---------------------------------------------------------------------------
void__fastcallTForm1::Button1Click(TObject*Sender)
{
//禁用當前選中的節點
if(TreeView1->Selected)
CrnEnableTreeNode(true,TreeView1->Selected);
}
//---------------------------------------------------------------------------
void__fastcallTForm1::Button2Click(TObject*Sender)
{
//啟用第二個節點
CrnEnableTreeNode(true,TreeView1->Items->Item[1]);
}
//---------------------------------------------------------------------------
為看到比較好的效果,可在測試時展開所有節點為:
TreeView1->FullExpand();