说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

如何给运行中生成节点的treeview控件加图标?????

编辑:说三道四文库 发布时间:2017-03-30 07:01
HTML文档下载 WORD文档下载 PDF文档下载
在运行中生成treeview的节点,然后个他们加上imagelist里面的图标,使用不相同的索引值。可是,当点击字节点的时候,图标会改变成父节点的图标,只是为什么?怎样才能使父节点和子节点有不同,且不改变的图标?
要看效果:http://www.comprg.com.cn/wz055.htm

Delphi环境下灵活的数据库树表实现 

 林琪

   我们目前正在开发的军队武器装备科技档案信息管理网络系统是面对全军的,管理全军武器装备科技档案的信息管理网络系统,由于全军在武器装备科技档案的管理模式上千变万化,对管理系统的需求也不相同,特别是,从调研的结果看:各单位的项目分类(信息分类)的级数是不定的,因此实现时一方面要考虑到通用性,另一方面也要保证用户使用的灵活性。

  

1 数据结构设计

在设计时可以采用两种数据存储方式(数据结构)。

1)信息分类表采用一个分类作为表的一条记录的方式进行存储,并由父类编号建立各类之间的关系,即:

分类号 
 类的含义 
 父类的编号 
 
0001 
 计算机 
   
 
0002 
 无线电 
   
 
… … 
 … … 
 … … 
 

2)这种分类表结构的建立不用动态生成表结构,但使用时相对麻烦。我们采用以下的表结构建立信息分类关系。这样的结构可以实现任意级的树型结构,如M层的一个结构:其中M是本单位的分类最大深度。类号要唯一识别每一个类。最上一级的分类号为全宗号+本级的分类代号,其他任意级的类其类号都为上一级的分类号+本级的分类代号。用户根据本单位档案的信息分类情况输入类信息,由系统动态创建表。

信息分类号
 全宗号
 类1含义
 类2含义
 类M含义
 分类深度
 
0001
 Zzb20
 电子
 计算机
   
 2
 
0002
 Zzb20
 电子
 无线电
   
 2
 
0003
 Zzb20
 通信
 卫星
   
   
 
0004
 Zzb20
 通信
 遥感
   
   
 
C4
 C6
 C20
 C20
 C20
 C1
 
XXFLH
 QZH
 L1
 L2
 LM
 FLSD
 

       在下面的例子中由于安全要求,对数据库表的结构作了简化,同时只使用了一些模拟数据以作说明。

  

2 树表外形设计

       由于Delphi提供的树表控件比较简单,外观不很美观,因此需要作一些“修饰”工作。为了强调重点,忽略了数据库操作如查询等,在例程中只使用了有关树表控件。

1)增加色彩

一般的树表控件没有底图,没有色彩,因此首先要解决色彩问题。解决的方法就是在树表控伯的ONDraw事件响应中增加底图显示代码。

procedure TForm1.Tree1CustomDraw(Sender: TCustomTreeView; const ARect: TRect; var DefaultDraw: Boolean);

begin

     with tree1.Canvas do                        //取树表控件的显示底板

     begin

     brush.color:=RGB(200,200,255);              //设置画笔颜色

     FillRect(ARect);                               //填充底板

 
  

     end; 

end;

这里仅为树表控件设置的底板颜色,实际上还可以设置底图,但由于底图的色彩不易控制,在调整树表结点时,容易出现颜色混乱的情况,而且只设置其颜色使树表控件的显示更加简洁。但只在ONDraw事件中设置颜色是不够的,还需要在其子项(结点)的显示事件中增加以下代码:

procedure TForm1.Tree1CustomDrawItem(Sender: TCustomTreeView;

  Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);

var

 Noderect:TRect;

begin

     with tree1.Canvas do

     begin

          case Node.Level of                  //根据不同的层次,设置不同的结点字体颜色

          0:   font.Color:=clBlue;

          …

          5:   font.Color:=clGreen;

          end;

      if node=tree1.Selected then       //为突出选中的结点,将选中结点字体颜色设置为红色

          font.Color:=clRed;

          NodeRect:=Node.DisplayRect(false);              //设置结点的显示方式

          brush.Color:=RGB(200,200,255);

          fillrect(NodeRect);                         //将结点的背景色与控件底板色设置为一致

     end;

end;

      

2)设置图标

       图像列表控件与树表控件可以算是“老搭档”,即为了显示不同层次的结点就需要为树表控件设置一个对应的图像列表,其设置方法比较简单,可以参见有关的Delphi程序设计手册。由于树结构层次不定,因此不能象常规的方法那样建立了树表与图像列表之间的关系即大功告成,这里还需要做的是建立树表结点与图像列表的关系,可以通过以下两个函数实现。

procedure TForm1.Tree1GetImageIndex(Sender: TObject; Node: TTreeNode);

begin

     node.ImageIndex:=node.Level;    //由结点的层次决定其对应图标在图像列表中的位置

end;

  

procedure TForm1.Tree1GetSelectedIndex(Sender: TObject; Node: TTreeNode);

begin

     node.SelectedIndex:=node.ImageIndex;

end;

  

3)  窗体激活事件响应

响应窗体激活事件时,需要作一些设置。由于在原系统中,此窗体涉及的功能和控件较多,许多功能的完成都需要激活另外的窗体。因此需要避免对数据库信息的重复设置。可以如下实现:

procedure TForm1.FormActivate(Sender: TObject);

var

 i:integer;

begin

 if first_in=false then            //区别是否首次激活,从而决定是否需要设置初始状态

 begin

  hint.Caption := '    提示: 正在准备,请稍候...';

  application.ProcessMessages ;

  tree1.Items.Clear;                    //设置第一个树表状态和颜色

  tree1.Color:=RGB(200,200,255);

  tree2.Items.Clear;                    //设置第一个树表状态和颜色

  tree2.Color:=RGB(100,200,255);

  qznode:=nil;                         //为了显示动态结构的分类层次,将各层树结点初始化为空

  for i:=0 to 5 do

   last_node[i]:=nil;

   stackdepth:=0;                       //设置栈初始深度为0

  show_tree1(0);          //调用show_tree1显示分类内容,参数0表示从第一层开始显示

  hint.Caption:='    提示: 数据成功调入';

  Application.ProcessMessages;

  end;

    first_in:=true;        

end;

  

4)  树表内容显示

由于树表结点层次的不确定,我们采用了递归显示的方法完成树表内容的显示。这里设置了4个变量,其含义为;

变量
 类型
 含义
 可选范围
 
cur_cds
 TQuery
 当前的查询集
 dbmd.qz,dbmd.fl1,dbmd.fl2,

dbmd.fl3,dbmd.fl4,dbmd.fl5
 
cur_str
 string
 当前的查询语句
   
 
num_str
 String
 当前的层次数查询语句
   
 
cur_level
 Integer
 当前层次
   
 
cur_node
 TTreeNode
 当前结点
   
 

这里利用栈确定父结点与子结点的关系,若某结点对应的分类深度比当前深度要大,就需要将此结点入栈,并惟此结点为父结点,以插入孩子结点方式递归地显示它的下一层结点,若当前层的结点都已显示完毕,就需要退栈,回到上一层次再作计算。主要的实现过程如下:

procedure TForm1.show_tree1(level:integer);

…                //变量声明

begin

  case level of              //根据输入参数,确定当前数据集、结点和查询语句

  0:

  begin

    cur_cds:=dbmd.qz;

    cur_node:=qznode;

    cur_str:='select distinct QZH from XXFLB ';

  end;

  1:

  begin

    cur_cds:=dbmd.fl1;

    cur_str:='select distinct L1 from XXFLB ';

    cur_str:=cur_str +' where  QZH= '+''''+dbmd.qz.Fields.Fields[0].value+'''';

  end;

  …

  end;

   cur_cds.close;                              //实现查询

   cur_cds.SQL.clear;

   cur_cds.SQL.Add(cur_str);

   cur_cds.open;

       for i:=1 to cur_cds.RecordCount do                     //遍历当前层的所有结点

          begin

            if level=0 then                             //若为第一层则调用add方法创建结点

               cur_node := tree1.Items.Add(cur_node,cur_cds.Fields.Fields[0].value)

            else                //否则,在上一结点基础上调用AddChild方法创建其子结点

      cur_node:=tree1.Items.AddChild(last_node[stackdepth-1],cur_cds.Fields.Fields[0].value);

          if level<5 then            //根据当前结点层次及结点内容确定当前类的分类深度

          begin

          case level of

          0:

          begin

          num_str:='select  FLSD from XXFLB ';

          num_str:=num_str +' where  QZH= '+''''+dbmd.qz.Fields.Fields[0].value+'''';

          end;

          1:

           …

          end;

          dbmd.sd.close;                               //执行深度查询

          dbmd.sd.SQL.Clear;

          dbmd.sd.sql.add(num_str);

          dbmd.sd.Open;

          val(dbmd.sd.Fields.Fields[0].value,cur_level,code); //取其深度

           if  cur_level>level then          //若当前层次未达到其分类深度

            begin

                      last_node[stackdepth]:=cur_node;     //当前结点入栈

                      stackdepth:=stackdepth+1;

                      show_tree1(level+1);                       //递归显示下一层次结点

             end;

           end;

           cur_cds.Next;          //取当前结果集中的下一条记录

           if i > cur_cds.RecordCount -1  then            //若当前层中全部记录显示完毕则退栈

                stackdepth:=stackdepth-1;

          end;

 
  

end; 

       另外第二个树表的内容显示的基本方法与此类似,所不同的是第二个树表的显示函数所带的参数为串型参数,该参数有两种可能,即为‘’或由点击第一个树表的事件产生串参数。若参数为空串,则要在第二个树表中显示所有项目,否则要根据参数创建过滤条件选择显示项目。具体方法可以参见源代码。

  

5)  树表调整

 
  

树表的调整即是对树表当前结点的条件,可以由两种事件产生,即树结点的扩展和点击树结点。由于一个全宗号下的分类种类很多,层次也可能很大,因此用户希望打开一个类时,与其无关的类就关闭,这样就可以保证仅有目前所选择的结点,而不需要用户利用滚动条在打开的结点中寻找。其实现要充分利用树结点的方法和属性。特别强调的是在对点击树表结点的响应事件中用到了结点的扩展方法,尽管对结点扩展事件的响应函数所实现的功能与之类似,但一定不能加入类似的结点扩展方法,如tree1.Selected.Expand(false)等,因为在扩展事件中调用扩展方法会导致事件循环,甚至死机。 

对第二个树表的调整与第一个树表的处理方式类似,但功能不同,这里不多介绍。

procedure TForm1.Tree1Click(Sender: TObject);

…                 //变量声明

begin

 if Tree1.Selected=nil then                  //若未选择结点,重置

 begin

   tree2.Items.Clear;

   tree2.Refresh;

   exit;

 end

 else

 begin

    tree2.Items.Clear;

    tree2.Refresh;

     str:=Tree1.Selected.Text;                   //取当前结点内容

     fatherNode:=Tree1.Selected.Parent;    //取当前结点父结点

     tempnode:=Tree1.Selected;                //设置当前结点

     while fatherNode<>nil do                  //由当前层开始关闭所有非当前结点,

//同时返回由其第一层祖先到当前结点所组成的串,作为第二个树表显示的参数。

      begin

           str:=fatherNode.Text+','+str;          //取父结点内容与当前结点内容联接

           usenode:=fatherNode.getFirstChild; //遍历父结点的所有儿子结点

           while usenode<>nil do

           begin

                if usenode<>tempnode then          //只要不是当前结点,则取消扩展状态

                   usenode.Collapse(true);

                usenode:=fatherNode.GetNextChild(usenode);

           end;

           tempnode:=fathernode;    //当前层结点处理完毕后,调整父结点为当前结点

           fathernode:=tempnode.Parent; //再取当前结点的父结点

      end;

      sibNode:=tree1.Items[0];          // 第一层结点的处理与其它层稍有差异

      while  sibNode<>nil do

      begin

        if  sibNode<>tempNode then

          sibNode.Collapse(true);

      sibNode:=sibNode.getNextSibling;

      end;

      tree1.Selected.Collapse(true);           //强制打开当前结点

      tree1.Selected.Expand(false);

      if tree1.Selected.HasChildren=false then   //若当前结点无孩子,

      begin

        show_tree2(str); //说明已构成一个完整的类,调用show_tree2函数实现第二个树表//的内容显示,参数str为完整的类名

        hint.Caption:='    提示: 数据成功调入';

        Application.ProcessMessages;

  end;

 end;

  

参考文献

1 徐新华,IDE和Object Pascal 语言,人民邮电出版社,1998.12 

2 郑城荣,曾凡奎等,Delphi 运行时间库RTL和组件库VCL技术参考,人民邮电出版社,1999.1 

1 徐新华,GUI编程技术,人民邮电出版社,1998.12
非常感谢!!!!
在你的treeview控件的Onchange事件中:
  if youttv.Selected<>nil then
    youttv.Selected.SelectedIndex:=youttv.Selected.ImageIndex;
即可保证图标不变。
treeview中的点有stateindex是选中后的图标值,你一定没改,所以是默认值,而你父图标可能也是默认值,所以一样了,你只要在生成子node 时同时设置imageindex和stateindex就可以了
HBuilder:最快的Web开发IDE 成功开发系统集成项目的六大建议 OS X平台上出现窃取比特币的木马 《近匠》第11期:Arrownock——移动社交构建师 面向企业:Google发布iOS版Google Admin应用 Github推出Education平台 师生免费享有微账号 平板的市场依然巨大:应用更丰富,Phablet设备存局限 免费的PCB数据3D转换工具 OBD++ XVL Converter Hadoop Namenode以regular方式启动代码流程分析 走进支撑过8亿用户的Yahoo!数据中心 Napier,一个引领Rackspace14年老兵功成身退 Twitter最新测试版被指仿Facebook的界面设计 成功求职者的自述:如何向应聘企业展示自身价值? 仅用移动开发服务:一分钱不花,开发native应用 苹果员工爆辞职内幕 Windows Phone 8.1被曝光信息汇总 Phaser:开源的HTML5 2D游戏开发框架 HTML5调查:做的好,收入不比iOS差 汽车巨人福特让“数据”说话 基调数据解读2014网购行业的3大变化 测测:用百度Clouda占卜移动互联网 微软的无奈:或允许Android应用运行于Windows平台 如何选择适合自己的编程语言 Google Now新增语音命令:生活简单一点,让爱更近一点 千万美金收购案:GetJar是一家怎样的公司 传苹果与时代华纳等公司合作,推新一代Apple TV 追本溯源 解析“大数据生态环境”发展现状 为Hadoop存储层增加对OpenStack Swift的支持 详解并行逻辑回归 在AWS上使用GPU实现分布式神经网络 大数据时代,看“小数据”如何支持决策 dbgrid 很奇怪的问题:任务兰上的时间显示? 疯狂的猜想-----致西瓜的眼泪(点点点) ActiveX Control如果做到背景透明? 怎么判断它们相等? 请教各位高手,谢绝低手回答。 请教各位高手,谢绝低手回答。 table中插入<IMG>时无法添满<TD> 诚征解答,我的家当全部奉上!关于解释器语法分析中分析方法的选择问题! 如何动态数据窗口分组?急急急!!!! 给分!!请提供一下netCDF的文件格式 outlook 无法写新邮件,提示,无法创建信纸,通讯薄加载失败,请指点! syntaxfromsql的问题 简单问题! java中可以使用类似于 X + =10;的语句? JSP中文存储问题!(高分求教) 如何得到当前日期的前一个月,结果是如‘200204’格式的字符串? 我该从哪里学起? 两个CDC问题,每个50分,不搞平均主义,先提出可^行^意见的拿分。 请问有没有湖北汉川市的朋友? 如何把一个自定义的类对象写进一个文件 INSERT时的一个小问题。 请求支援,一个初级问题,关于动态加载窗体 请求支援,一个初级问题,关于动态加载窗体 线程里执行查询时碰到的错误。。。。说BDE引擎内存不足。。请各位多多指教 delphi Microsoft Development Environment中如何拖拉web form控件? 关于cloudscape Win2000??? 如何在image或者PICTURE控件中保持图像的比例 小问题:使用image控件时,能不能用mask将图片的背景色给屏蔽掉? 如何在javascript中调用COM对象? WinCE emulator !!!!!! *************2000分求救!!!SOS!!!************** 线程里执行查询时碰到的错误。。。。说BDE引擎内存不足。。请各位多多指教 刚才我发了一个贴子,请问我怎样结贴?(不好意思,我真笨) JCreator LE 使用!?各位兄弟姐妹,用过JCreator LE的来给小弟指指路好吗? dbgrid 各位,请看下面一段有关线程同步的代码: 大家上来帮我看一下http://www.csdn.net/expert/topic/613/613969.xml?temp=.7868463 大家上来帮我看一下http://www.csdn.net/expert/topic/613/613969.xml?temp=.7868463 简单的一道题,各位高手指点一下把! 大家上来帮我看一下http://www.csdn.net/expert/topic/613/613969.xml?temp=.7868463 美丽的故事悲伤的结局 大家上来帮我看一下http://www.csdn.net/expert/topic/613/613969.xml?temp=.7868463 98安装故障,急!请帮看看! 大家上来帮我看一下http://www.csdn.net/expert/topic/613/613969.xml?temp=.7868463 oracle 入门的书籍,请大家推荐!本人是菜鸟现在想学习 oracle请大家多多指教!!!!! 谁有好的VB电子书籍 不会使用网上的控件,谁教我? **********四大网站被黑!!!********** 怎麼寫這兩條SQL語句;(1)顯示當前數據庫?(2)顯示當前所有用戶表? 急,謝謝 现用棱长为1cm的若干小立方体按如图所示的规律在地上搭建若干个几何体,图中每个几何体自在线等现用棱长为1cm的若干小立方体按如图所示的规律在地上搭建若干个几何体,图中每个几何体 某班分成两个活动小组,第一组26人,第二组22人,根据学校器材的数量,要将第一组的人数调整为第二组人数的一半,应从第一组调多少人到第二组去? 小红每天要赶到1000米的学校上学.一天小红以80米/分的速度出发,小红的爸小红的爸发现她忘了带数学书,于是爸爸;立即以180米/分的速度去追小红,并在途中追上她.你知道爸爸在追小红时离学 现用棱长为1cm的若干小立方体按如图所示的规律在地上搭建若干个几何体,图中每个几何体自上而下分别 叫第一层、第二层...、第n层(n为正整数),其中第一层摆放1个立方体,第二层摆放4个 六(6)班分成两个组进行课外活动,原计划第一组22人,第二组23人,根据活动要求,需要将第一组的人数调整为第二组的2倍,应从第二组调多少人到第一组去?大家尽量不要用方程, 一些孩子在沙滩上玩耍,他们把石子堆成许多堆,其中一个孩子发现从石子堆中任意选出6堆,其中至少有两堆石子数的差是5的倍数,你能说说他的结论对吗?为什么? 六年级语文第10页小练笔作文 小学二年级语文教学中应注意的问题 夏季,树木有根吸收来的水分主要用 A.植物的生长 B.果实的形成 C.种子的形成 D.蒸腾的作用 不用太多, 我要小学苏教版三年级语文视频教学 1.一种黄铜由锌和铜按3:7熔铸成,要生产45吨黄铜,要锌铜各多少吨?用比例解2.四分之三x - 四分之一x + ( )*5=36.6 已知正确x=4.2 完整的方程是什么 3.平行四边形abcd的周长44厘米,ad边上的高7 意林读后感500字,5篇,内容不一 怎么做好小学二年级语文教学 求有故事情节丰富哲理的青春励志小说 意林2012年度感动卷读后感400-500字 求一个800字的微小说,青春励志的或校园故事 小英从家到学校,原计划步行用10分钟,实际只用8分钟,)%. 请用恰当的词语替换句子中写 “ ” 的词,并在句子后面的括号里.1.假若不“爱惜”时间,你就一事无成.( )2.掌声“掩盖”了观众的议论声.( )3.同学们不会“责怪”我的.( )4.这道题这 用棱长为1 的若干小立方体按如图所示 的规律在地上搭建若干个几何体,图中每个几何体自上而下分别叫第一层用棱长为1的若干小立方体按如图所示的规律在地上搭建若干个几何体,图中每个 用5个棱长是1厘米的小正方体组成的立体图形的表面积是? 500字的 实验小学六年级一班学生体育达标情况如下: 优秀的人数占全班人数的30%,良好的人数占全班人数的45%,实验小学六年级一班学生体育达标情况如下:优秀的人数占全班人数的30%,良好的人 人教版三年级下册语文视频教学录像急需!急需! 小学六年级语文关于给予类的文章 二次函数第二题 人教版小学语文五年级下册《打电话》的教学视频(加到满分!) 百米赛跑,聪聪和佳佳速度比是5:4,当聪聪到达终点,佳佳距离终点多少米? 由于墨水被盖,一道数学题仅能见到如下文字:已知二次函数y=x的平方+bx+c的图象过点(1,0)……求证:这个二次函数图象的对称轴是直线x=2.(1)根据现有信息,你能求出已知条件中的二 人教版小学三年级视频教学(语文 数学)哪里有 狂热的球迷们在体育场看了一场扣人心弦的足球比赛怎么缩句 求视频:二年级上册语文( )鸟叫声( )火车声( ) 求视频:人教版小学语文四年级下册第六单元作文教学视频 小学六年级作文“学会生存”“自我保护” 小学一年级语文上册,一年级语文上册视频哪有,在哪可以学习小学一年级语文上册,且有一年级语文上册试题和一年级语文上册课本的相关内容 正方体也叫(),它是由()个()的正方形围成的立体图形. 关于自我保护的作文题材. 《世界上最美的是什么》教学设计与反思 小红从家到学校共1200米,她走了150米后想起书本个忘记拿了,于是马上回去取,这样小红到学校共走了多少路? 一般就行 快啊,要教育科学出版社的!我会提高悬赏的! 明明家距学校1200米.明明7:00从家出发去学校,每分钟走60米,走了10分钟后他想起忘带了作业本.于是他以90米/分的速度回家去拿,并以相同的速度赶去学校.明明7:30能赶到学校吗? 一件自我保护的事六年级作文 《世界上最美的是什么》教案及反思 树木的组成成分是什么? 六年级下册语文第四单元作文,关于自我保护的作文 某班上学期参加体育活动小组的人数占全班人数的58%,有21个同学未参加.本学期参加体育活动小组的人数比上学期多17人,问本学期该班参加体育活动小组的人数占全班的百分之几? 大树由那几部分组成 有一个六个小正方体组合而成的几何体,每个小正方体的六个面上都分别写着-1,2,3,-4,5,-6六个数字,那么图中所有看不见的面上的数字和是【 】 少先队员参加书法和美术小组,其中参加书法小组的人数占总人数的58%,后来又16人退出书法小组参加美术小组,这时,两个小组人数相等,两个小组原来各有多少人?(不要设x和y,可以用解方程或 大树是由哪些部分组成的呢? 用小立方体搭成一个几何体,使它的主视图和俯视图如图所示,搭建这样的几何体最多要几个小立方体.最少要几个?并画出最多和最少时几何体的左视图.口口口口口口口 主视图口口口口口口口 某班原分2个小组活动,第一组26人,第二组22人,根据活动器材的数量,要将第一组人数调整为第二组人数的一半,应调多少人到第二组, 大树吊针注射液,大树营养液,大树伤口涂抹剂,根腐灵,生根液,土壤消毒剂,大树蒸腾抑制剂哪里在销售? 六年级语文作文,读《一夜的工作》有感,好的加100,不好的加50 半圆分成两个小组进行课外体育活动第一组26人,第二组22人,要将第一组的人数调整为第二组的一半,应把第一组掉多少人到第二组? 关于青春励志的文章.注意是青春励志,最好是名人的,或者是名人写的. 意林系列的小说哪本好? 两组活动,一组26人,另一组22人,要将第1组人数调整为第2组人数的一半,应从第1组调几人到第2组去 用方程解 度是多少?小红从家到学校,走了8分钟,每分钟走50米,从学校到体育馆走了800米,用了12分钟.小红从家走到体育馆平均速度是多少?
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘