如何禁用一个树节点(Disable Tree Node)

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 __fastcall CrnEnableTreeNode(bool bEnable, 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 __fastcall TForm1::TreeView1CustomDrawItem(TCustomTreeView *Sender,
      TTreeNode *Node, TCustomDrawState State, 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 __fastcall TForm1::TreeView1Changing(TObject *Sender, TTreeNode *Node,
      bool &AllowChange)
{
    // 欲选中这个节点时,判断如果当前节点被禁用则禁止改变原节点的选择状态
    AllowChange = (int(Node->Data) != 0xFFFF);
}
有以上的实现,效果基本就出来了:
Disable tree node

测试代码:
//---------------------------------------------------------------------------
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]);
}
//---------------------------------------------------------------------------
为看到比较好的效果,可在测试时展开所有节点为:
TreeView1->FullExpand();

posted on 2008-01-02 09:19 lovetiffany 阅读(923) 评论(1)  编辑 收藏 引用

评论

# re: 如何禁用一个树节点(Disable Tree Node) 2008-01-02 14:35 <a href=http://minidx.com>minidxer</a>

转载文章标出来比较好吧?  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2008年1月>
303112345
6789101112
13141516171819
20212223242526
272829303112
3456789

导航

统计

常用链接

留言簿(4)

随笔档案

网站收藏

搜索

最新评论

阅读排行榜

评论排行榜