如何禁用一个树节点(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__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();

时间: 2016-10-07

如何禁用一个树节点(Disable Tree Node)的相关文章

DOM树节点解析

DOM是解析XML文件的官方标准,它与平台和语言无关.DOM解析将整个XML文件载入并组装成一棵DOM节点树,然后通过遍历.查找节点以读取XML文件中定义的数据.由于DOM解析中把所有节点都载入到内存中,因而它比较耗资源,而且它需要把整棵节点树构建完成后开始读取数据,因而它相对性能也不好:不过由于它在内存中保存了DOM节点树,因而它可以多次读取,并且它的节点树定义比较容易理解,因而操作起来比较简单.关于性能,有人对一些常用的解析方法做了比较: 单位:s(秒)转自:http://www.cnblo

datagrid-easyui点击树节点添加选项卡,且选项卡内加载数据表格为什么我的代码只能实现一个?

问题描述 easyui点击树节点添加选项卡,且选项卡内加载数据表格为什么我的代码只能实现一个? $("#tr1").tree({ url:'tree_data.json' }); //双击树的节点添加面板 $("#tr").tree({ onDblClick:function(node){ addTab(node); } }); //添加面板 function addTab(node){ $("#ta").tabs('add',{ title:n

ext tree 定位树节点

问题描述 树 : Ext.tree.TreePanel树节点 : new Ext.tree.AsyncTreeNode现在的问题是.当我通过条件定位树节点的时候.树的竖向滚动条,有的时候不会在可视范围内.网上有说是用scrollIntoView(),但是我一直获取不到当前被选择节点的div对象.期待解决方案...... 问题补充:clue 写道 解决方案 node.getUI().getEl()建议多翻翻API文档解决方案二:其实 直接找到节点 .focus();就可以了 没必要人为的 去定位.

sqlserver 存储过程-sql server 存储过程 树节点 每次加载一个节点

问题描述 sql server 存储过程 树节点 每次加载一个节点 有一张数据表A,表字段:treeid,treeparentid,treename三个字段,现在要用存储过程建一个树目录结构的菜单,初始化时,只加载根节点和所有的一级子节点,一级子节点下面的子节点初始化时不加载,初始化完成之后,我们点击一级子节点菜单,它才会加载选中的节点菜单下面的子节点,每次加载一级节点,无限次加载.非常急,在线等,本人第一次在CSDN上提问,不知道要不要分,好像有几十分,都给,写存储过程的时候,请把存储过程的几

一个简单的CheckBox Tree实现

CheckBox Tree是一个十分常用的UI组件,它能使用户方便地按特定规则勾选树中的节点.本文实现了一种简单的Checking规则:当勾选了某节点后,该节点的所有下级节点全部被勾选:当取消勾选某节点后,该节点的所有下级节点全部被取消勾选.(2009.08.05最后更新) 实现CheckBox Tree的常用方法,就是使用JCheckBox作为JTree的TreeCellRendrer,并且需要实现特定的Checking规则来勾选/取消勾选CheckBox. 1. 树节点 DefaultMut

[算法系列之二十四]后缀树(Suffix Tree)

之前有篇文章([算法系列之二十]字典树(Trie))我们详细的介绍了字典树.有了这些基础我们就能更好的理解后缀树了. 一 引言 模式匹配问题 给定一个文本text[0-n-1], 和一个模式串 pattern[0-m-1],写一个函数 search(char pattern[], char text[]), 打印出pattern在text中出现的所有位置(n > m). 这个问题已经有两个经典的算法:KMP算法 ,有限自动机,前者是对模式串pattern做预处理,后者是对待查证文本text做预处

[算法系列之二十三]线段树(Interval Tree)

一 背景 在信息学竞赛中,我们经常会碰到一些跟区间有关的问题,比如给一些区 间线段求并区间的长度,或者并区间的个数等等.这些问题的描述都非常简单,但是通常情况下数据范围会非常大,而朴素方法的时间复杂度过高,导致不能在规定时间内得到问题的解.这时,我们需要一种高效的数据结构来处理这样的问题,在本文中,我们介绍一种基于分治思想的数据结构--线段树. 二 简介 线段树是一种二叉树形结构,属于平衡树的一种.它将线段区间组织成树形的结构,并用每个节点来表示一条线段.一棵[1,10)的线段树的结构如图1.1

EasyUi combotree 实现动态加载树节点_javascript技巧

推荐阅读: 简介EasyUI datagrid editor combogrid搜索框的实现 EasyUi中的Combogrid 实现分页和动态搜索远程数据 easyui 1.2.4例子中并没有给出动态加载树节点的例子,只好自己研究. 从源码中可知可以看出combotree 是继承 combo 和 tree两个控件,所以在展开其下级子节点时,把combotree内置的tree的options选项的url重置成一个动态取选择值的url,代码如下: $('#cc').combotree({ url:

treepanel-extjs3 treePanel 如何监听delete按键 并删除树节点

问题描述 extjs3 treePanel 如何监听delete按键 并删除树节点 我用的extjs3.问题困扰了我好长段时间,求高手关注啊! 我的代码如下: var leftTreePanel = new Ext.tree.TreePanel({ id : 'left_tree_panel', autoScroll : true, animate : true, enableDD : true, enableDrag:true, ddGroup: "GridDD", title :