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

測試代碼:
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
// 禁用當前選中的節(jié)點
if(TreeView1->Selected)
CrnEnableTreeNode(true, TreeView1->Selected);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
// 啟用第二個節(jié)點
CrnEnableTreeNode(true, TreeView1->Items->Item[1]);
}
//---------------------------------------------------------------------------
為看到比較好的效果,可在測試時展開所有節(jié)點為:
TreeView1->FullExpand();
posted on 2008-01-02 09:19 lovetiffany 閱讀(942) 評論(1) 編輯 收藏 引用