TTreeView是VCL中提供的樹列表控件,樹的每個(gè)節(jié)點(diǎn)是一個(gè)TTreeNode類,TTreeNode組件的屬性和方法可以參考Borland提供的幫助(雖然不如MSDN全面,但有總比沒有強(qiáng))。實(shí)際應(yīng)用中我們可能需要禁用某個(gè)節(jié)點(diǎn)(界面上反應(yīng)的效果是:節(jié)點(diǎn)字體呈灰色顯示,節(jié)點(diǎn)無法選中等)。但是VCL沒有提供Node->Disable();或Node->Enable = false;這樣的功能,我們只好自己動(dòng)手實(shí)現(xiàn)了。首先我們需要為每個(gè)節(jié)點(diǎn)設(shè)定一個(gè)標(biāo)志,用來標(biāo)識(shí)此節(jié)點(diǎn)是否可用,標(biāo)識(shí)方法有很多,比如判斷節(jié)點(diǎn)的文本(Text),節(jié)點(diǎn)的絕對索引值(AbsoluteIndex),節(jié)點(diǎn)的索引(Index)加縮進(jìn)(Indent)等,在本例中我們用節(jié)點(diǎn)的Data屬性作標(biāo)識(shí)(一個(gè)void
*型數(shù)據(jù),其實(shí)可以存放N多東西)。如果在你的應(yīng)用中恰好用了Data屬性,就另外想個(gè)用來作標(biāo)志的方法吧。:)
我們寫一個(gè)自定義函數(shù),用來啟用/禁用一個(gè)節(jié)點(diǎn):
void __fastcall CrnEnableTreeNode(
bool bEnable, TTreeNode *pNode)
{
pNode->Data = bEnable? NULL: (
void *)0xFFFF;
// 本文轉(zhuǎn)自 C++Builder 研究 -
http://www.ccrun.com/article.asp?i=1015&d=r2tf61
pNode->TreeView->Invalidate();
}
然后考慮如何達(dá)到禁用節(jié)點(diǎn)的效果,前面說了,我們只需實(shí)現(xiàn)這兩個(gè)效果:
1. 節(jié)點(diǎn)字體呈灰色顯示
2. 節(jié)點(diǎn)無法選中
節(jié)點(diǎn)字體呈灰色顯示可以通過TreeView的OnCustomDrawItem事件中的自繪實(shí)現(xiàn),在設(shè)計(jì)時(shí)狀態(tài),選中TreeView,Events選項(xiàng)卡雙擊OnCustomDrawItem事件,添加以下代碼:
void __fastcall TForm1::TreeView1CustomDrawItem(TCustomTreeView *Sender,
TTreeNode *Node, TCustomDrawState State,
bool &DefaultDraw)
{
if(
int(Node->Data) == 0xFFFF)
{
Sender->Canvas->Font->Color = clGray;
}
}
節(jié)點(diǎn)無法選中則可以通過TreeView的Changing事件來處理,在設(shè)計(jì)時(shí)狀態(tài),選中TreeView,Events選項(xiàng)卡雙擊OnChanging事件,添加以下代碼:
void __fastcall TForm1::TreeView1Changing(TObject *Sender, TTreeNode *Node,
bool &AllowChange)
{
AllowChange = (
int(Node->Data) != 0xFFFF);
}
有以上的實(shí)現(xiàn),效果基本就出來了:

測試代碼:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
if(TreeView1->Selected)
CrnEnableTreeNode(
true, TreeView1->Selected);
}
void __fastcall TForm1::Button2Click(TObject *Sender)
{
CrnEnableTreeNode(
true, TreeView1->Items->Item[1]);
}
為看到比較好的效果,可在測試時(shí)展開所有節(jié)點(diǎn)為:
TreeView1->FullExpand();