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

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

编辑:说三道四文库 发布时间:2017-06-25 10: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就可以了
VB中多级下拉列表的实现 VB中防止将重复项目添加到列表框控件中 VB中实现菜单分割 VB中实现带预览的对话框 VB中实现同一窗口的多个实例及控件的动态增减 VB中阴影字体的实现 VB自定义数据结构的传输转换 Visual Basic 窗体背景花纹的实现 Visual Basic 中的界面设计原则和编程技巧 Visual Basic 中文本框处理技巧集萃 Visual Basic 中字符淡出淡入的实现 Visual Basic窗体背景花纹的实现 Visual Basic下工具条的制作 Visual Basic中的界面设计原则和编程技巧 Visual Basic中在同一界面输入大量数据的几种方法 VisualBasic中的界面设计原则和编程技巧 VisualBasic中用户界面的设计原则 把 VB 标准的工具栏变成平面式 把窗体卸载干净-VB资料 保持初始的窗体大小-VB资料 编程实现将所有窗口最小化-VB资料 不规则形状窗口详细说明 -VB资料 不用 API ,直接调用关联的程序 -VB资料 处理过程时的鼠标显示 -VB资料 窗口处理技巧大全 -VB资料 窗口事件的发生顺序-VB资料 VB创建不规则窗口 VB创建透明窗体 VB创建位图菜单 VB创建无 Icon 的窗口 打开 Win95 的创建快捷方式窗口-VB资料 用jbuilder7和weblogic7建立实体BEAN的问题? 寻图标资源网站 请大家帮忙,着急,在线等待 如何给分? ----->help<------在线等待!!!!!!!!!!! EXE文件格问题 谁有最新版的Nusphere PHPED V3.1的下载地址啊! DbGrid为什么不能在mdiChild类型的窗口中显示 创建数据库创建到一半的时候就报错,不知道是什么原因,请大家帮忙!!! zhu8888一步一步住前走来接这100分。我是守信的。 PB中如保打开html文件? int CWinThread::Run() 问斑竹! 怎样在jsp中调用oracle817中的过程和函数?在线等待回复! 如何改变CStaic控件的背景色 各位大虾,给我介绍几本C++的名著好吗 关于水晶报表,控制分页显示。急急急急!!!! help:--------------->在线热切等待! 天啊我都快疯了 是不是用户对象必须继承System.Web.UI.UserControl 怎样把shs片断对象各式的图表转换成网页可以引用的图形各式?? 如何拖文件 怎样拦截键盘输入 【送分有理】好不容易混成五个三角,感谢新老朋友的大力支持啊^_* Exchange Web Service 问题? 关于远程连接问题!在线等! 这一SQL语句错在哪里? 在Delphi中,用SQL脚本更新存储过程? ★★★★★突然想到一个realloc的使用问题,请指教!★★★★★★ 在线等候!急 搜了搜,关于word和图片格式的文件都是文件上传到数据库并显示,可是怎么让一个word对象保存到数据库并显示呢? 这条sql语句怎样写 谁知道计算机等级考试在那个网站能查分(2002年下半年二级C)? 求助,如何在SQL Server数据库设计好之后,把它打包,生成setup.exe可执行安装程序。 NT无盘高手进 請問哪位可以提供點完成端口的資料阿? 网络的不通 如何把VC++中的输入IP地址的控件导出来? VS.NET的第六、七张碟有什么用呀? B/S,如何当一个form为非编辑模式的情况下让其中的一个field为编辑模式 form提交的有效性检查问题 把 MYSQL* mysql作为参数据传递处理 出现错误 有关98下的声音问题,来者有分 NT/2000下,怎么将应用程序在开机时自动加载?谢谢,送高分,我会再加的 金山毒霸不能卸载?! 教你发短信不收费!!!!!!!!!!! 关于颜色值格式的问题 关于设置主键的问题! 我想说的是,漏题不仅仅在湖北. Win2000环境下,VB程序如何能得到计算机当前的CPU使用率? 系统错误:&h800706BA(-2147023174) 请问这个错误 一般是什么地方出问题 谢谢 急急急急急急!!( I haven’t written to him for a long time ,because I don’t know his p____address. we__(not see)each other for a long time 英语翻译我今天的发言题目是:“基督教在西方民主政治发展中的作用”.我认为:西方民主政治是在自身文化的历史进程中形成和发展的,其中宗教,特别是基督教始终起着独特的复杂的作用. National Day is coming.Sally and her parents are taking a short vacation这篇文章全文是什么 find out 造句 My English is my best friend? ---I haven't written a letter to him for a long time.how about you?--Well,I____just now.A.i wrote it B.wrote one C.did it D.did one请详细说明原因,为什么不选D find out怎么造句 怎样提高英语的阅读和完形的正确率 listening I dark to programme sat in favourite there my the(连词成句) find the answer还是find out the answer? 怎样提高英语完型填空和阅读的正确率 英语翻译Any provision of this Agreement which is prohibited by or unlawful or unenforceable under any applicable law actually applied by any court of competent jurisdiction shall,to the extent required by such law,be severed from this Agreement a 用find造句 冬天生的女孩用什么英文名字好 by the end of the last year ,the young man had (won this match five times)对刮号内提问 英语翻译Sec.6 Provides that the issue of a business registration certificate shall not be deemed to imply that the requirements of any law in relation to such business or to the persons carrying on the same or employed therein has been complied w how do you like the book?it's quite different fhow do you like the book?it's quite different from i read last montha that b which c the one d the one.that This happens to me all the time in the school library翻译句子 英文合同部分内容求翻译Contractor commits to finish the manufacturing of the tool(milestone 1) according to the updated time schedule 27.09.2007 at latest. The invoice of the Contractor takes to consideration the payment made to the Subcont 引导词 that可代替定语从句中的表语 that可以省略吗?Our school is no longer the school that it used to be he is not the star that he was 两句中that都可以省略吗? I have___him for a long time.空上请帮忙填出“理解,懂得”的表达.我想这得用延续性动词吧,该用什么词呢? National Day is coming,We'll have ten days away.(改错)这里有一处错误,请指出并改正!1 沓无人烟是什么意思?谢谢各位啊 1.The existence of oil wells has been known for a long time.为什么用has 而不用have 真名王霞 取个好听的微博名和英文名,最好跟真名挂钩 who can help me"all the bits and pieces start to fit" who will do me a favor?what it's the meaning of that sentence i posted,i don't even know how to use this sentence yet.i will probably use it in the wrong place if you guys do not help me correct m "i have been for a long time"中,"have" 为什么不用"had"?"been"不代表已经结束了么? 亲情是把双刃剑或是亲情的奇迹,以此写一篇作文,或者告诉我论据也可以 who can help me please translate:as the foreigners are activewe make a point of sitting still,as they are scientific,we go in for planchette writing,as thety wear short jackets,we wear long gowns,as they pay attention to hygiene,we eat flies,as they The national day is coming,we‘ll have seven days ——空里填off么? 求翻译.中文 -> 英文 内容如下一部出色的游戏作品,不仅需要丰富的关卡剧情来丰满内容,同时还需要展示出独特且能够引起玩家共鸣的场景.场景设计的感染力显得尤为重要.总得来说,感染力 HELP ME WHO CAN HELP ME?受到特大刺激后如何调控情绪? Tomorrow i will wake ( ) at seven.A up B down C to 选什么,为什么? We will have three days next week.空格填什We will have three days next week.空格填什么A.off B.leave C.away. 做英语阅读和完形有时候读不懂我现在高三马上高考了!50天!我把从初一到高中5本必俢的单词和短语都记了!为什么我做完形填空和阅读的时候有时候读不懂呢?做简单的就知道意思!为什么?这 she has a q___ berakfast and then went to school 很,非常(汉译英)—— (用一个词)—— ——(用两个词) —— —— ——(用三个词) 强调句与定语从句的区别 she___ ___ ____ ____,and then went out 他洗完衣服,然后就出去了 中译英:“根据下列信息写出单词” 定语从句和强调句有什么区别?强调句和定语从句的区别 In time of danger every minute___原题就这样。 以‘我最喜爱的演员’为题写一篇英语短文,要求语句通顺内容丰富不少于50词写一下金贤重 强调句和定语从句的区别如果强调句中呗强调部分是主语的话怎么和定语从句进行区别比如It was Smith who sent me the letter.这个是什么句子?如果按去掉框架之后的句子完整程度来看是强调句,但 she wore herself and then went out错误在哪 英语-请问这两句话表达的意思有啥区别吗?How long have you worked there?How long have you working there? 强调句与定语从句区别请问怎么区分强调句与定语从句,谢谢! I occur in every minute,two times in every moment,but not one time in a hundred years.What am 猜一个字母. 【英语】这两句话有什么区别?从塔顶看,我们能看到一个漂亮的工场 从塔顶看,这个工场很漂亮怎么翻译?又有什么区别,这课学的是分词,是用seeing 还是seen啊 如何区分定语从句和强调句?有些定语从句与强调句很相似,怎么区分? She sat there and______(没做任何事情) We haven't __each other for a long time.A.known B.recognized C.realized D.got to known问什么选A及翻译. 英语翻译我今天的发言题目是:“基督教在西方民主政治发展中的作用”.我认为:西方民主政治是在自身文化的历史进程中形成和发展的,其中宗教,特别是基督教始终起着独特的复杂的作用. Time,every minute and every second is a distance in the draw. We haven't known each other for a long time since my good friend _____(leave)here. 英语翻译原文:韶关市地处粤北山区,与湖南、江西交界,素有“三省通衢”之誉,是古代岭南通往中原的最重要关口,今天更是广东通往内地的交通枢纽——京广铁路、京珠高速公路、国道105线 he stayed calmly in time of danger Does he dare go out in time of danger单次找错 ——Have you known each other for long?——Not very long,_____ we started to work in this company.A.sinceB.beforeC.whenD.after选哪个?为什么? 英语翻译原文:维持生命必须的食物有三类.一是碳水化合物.碳水化合物广泛存在于动、植物,包括糖、淀粉及纤维分子(cellulose),为人类提供能量.碳水化合物还能合成生物过程所必须的葡
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘