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();
(编辑:aniston)
|