• C# TreeView的用法


    一:TreeView.Items[0].Expanded := True; // 展开第一个节点
    二:TreeView.Items[0].Item[0].Selected := True; // 移动到第一个节点的第一个子节点 
    找当前节点的下一个节点,按序号找如下:
    if treeview1.Selected.GetNext<>nil then
    treeview1.Selected.GetNext.Selected:=true;
    TreeView1.SetFocus;

    找当前节点的下一个同层兄弟如下:
    if treeview1.Selected.getNextSibling<>nil then
    treeview1.Selected.getNextSibling.Selected:=true;
    TreeView1.SetFocus;
    TreeView.Selected.getPrevSibling  //当前选中节点的上一个兄弟节点
    TreeView.Selected.Parent          //  当前选中节点的父节点 

    getfirstchild是跳到该节点子结点中的第一个
    getlastchild是跳到该节点子结点中的最后一个

    如果你是想跳到同层兄弟结点的第一个
    if treeview1.selected.parent<>nil then
    treeview1.selected.parent.getfirstchild.selected:=true
    else
    treeview1.items.item[0].selected:=true;

    如果你是想跳到同层兄弟结点的最后一个
    if treeview1.selected.parent<>nil then
    treeview1.selected.parent.getlastchild.selected:=true
    else
    treeview1.Items.Item[treeview1.Items.Count-1].Selected:=true;
    TreeView的使用方法


    基本信息:
    TreeView 是一个显示树型结构的控件,每一个节点都是一个新类,
    使用具有代表性
    每个节点都有四个值:
    TEXT:显示文字 Image Index:显示图形序号
    Selected Index:
    State Index:

    (1)建立目录项(本例中使用的TREEVIEW名称为:TvwTips)

    增加根目录下的节点:(节点)
    var
    CatNode : TTreeNode; //先建立一个TREEVIEW使用的子对象
    begin
    TvwTips.SetFocus; //将焦点置到这个TREEVIEW控件上
    { 在根标题下建立一个新的子标题 }
    CatNode := TvwTips.Items.AddChild(
    TvwTips.Items.GetFirstNode,'New Category' );
    CatNode.ImageIndex := 1;
    CatNode.SelectedIndex := 2;
    CatNode.EditText; { 允许用户改变这个标题 }
    end;

    增加下一级目录(内容):
    var
    ParentNode, TipNode : TTreeNode; //先建立TREEVIEW使用
    的子对象
    VersionNum : Integer;
    begin
    TvwTips.SetFocus; //将焦点置到这个TREEVIEW控件上
    VersionNum := TMenuItem( Sender ).Tag; { Ver num of new tip }
    ParentNode := TvwTips.Selected; { 取出当前的选中节点 }
    if ParentNode.Level = nlTip then{ Parent cannot be a tip node }
    ParentNode := TvwTips.Selected.Parent;

    TipNode := TvwTips.Items.AddChildObject( ParentNode,'New
    Subject',Pointer( VersionNum ) );
    TipNode.ImageIndex := 3; { Normal tip bitmap }
    TipNode.SelectedIndex := 4; { Highlighted tip bitmap }
    TipNode.MakeVisible; { Move new tip node into view }
    TipNode.EditText; { Immediately allow user to edit subject }
    EnableTreeViewFunctions( TipNode.Level );
    RtfTip.Clear;
    RtfTip.Modified := False;
    end;

    (2)说明
    TvwTips.Items.GetFirstNode 返回TREEVIEW的第一个节点,函数类型为
    :TTreeNode
    TvwTips.Items.Count 返回当前TreeView的全部节点数,整数
    TvwTips.Selected.Level 返回当前选中节点的在目录树中的级别,
    根目录为0
    TvwTips.Selected.Parent 返回当前选中节点上级节点,函数类型为
    :TTreeNode

    三、下面这段程序是用TREEVIEW连数据库及一些操作:
    unit bmzd;

    interface

    uses
     Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
     StdCtrls, ComCtrls, Db, DBTables, ImgList, Buttons, ExtCtrls, Grids,
     DBGrids;

    type
     Tfrmbmzd = class(TForm)
       Panel1: TPanel;
       cmd_new: TBitBtn;
       cmd_delete: TBitBtn;
       cmd_exit: TBitBtn;
       tvwcode: TTreeView;
       ScrollBox1: TScrollBox;
       GroupBox2: TGroupBox;
       Label3: TLabel;
       Label2: TLabel;
       Label1: TLabel;
       Label4: TLabel;
       Label5: TLabel;
       Edit2: TEdit;
       Edit3: TEdit;
       Edit4: TEdit;
       Edit5: TEdit;
       ImageList1: TImageList;
       Edit1: TEdit;
       cmd_save: TBitBtn;
       cmd_update: TBitBtn;
       procedure FormShow(Sender: TObject);
       procedure FormClose(Sender: TObject; var Action: TCloseAction);
       procedure cmd_newClick(Sender: TObject);
       procedure cmd_deleteClick(Sender: TObject);
       procedure Edit2KeyPress(Sender: TObject; var Key: Char);
       procedure tvwcodeChange(Sender: TObject; Node: TTreeNode);
       procedure cmd_updateClick(Sender: TObject);
       procedure BitBtn2Click(Sender: TObject);
       procedure tvwcodeClick(Sender: TObject);
     private
       { Private declarations }
         function LoadCode(crTbl:TDBDataSet):Integer;
    function GetLevel(sFormat,sCode:String):Integer;

     public
       { Public declarations }
     end;

    var
     frmbmzd: Tfrmbmzd;
     ii:integer;
     tv:ttreenode;
     const
    SCodeFormat = '222222';   //科目代码结构
    SFirstNodeTxt   = '部门分类';

    implementation

    uses dm;


    {$R *.DFM}

    function tfrmbmzd.LoadCode(crTbl:TDBDataSet):Integer;
    var NowID,sName,ShowTxt:String;
    i,Level:Integer;
    MyNode:array[0..6]of TTreeNode;
    //保存各级节点,最长支持6级(重点)
    begin
    Screen.Cursor:=crHourGlass;
    Level:=0;
    With frmdm.tabbm do
    begin
    try
    if not Active then Open;
    First;
    tvwCode.Items.Clear;
    //以下是增加第一项
    MyNode[Level]:=tvwCode.Items.Add
    (tvwCode.TopItem,SFirstNodeTxt);
    MyNode[Level].ImageIndex:=0;
    MyNode[Level].SelectedIndex:=0;
    //以上是增加第一项
    While Not Eof do
    begin
    NowID:=Trim(FieldByName('bumeng_id').AsString);
    ShowTxt:=FieldByName('bumeng_name').AsString;
    Level:=GetLevel(SCodeFormat,NowID);
    //返回代码的级数
    //以下是增加子项
    //以下用上一级节点为父节点添加子节点
    if Level>0 then//确保代码符合标准
    begin
      MyNode[Level]:=tvwCode.Items.AddChild
    (MyNode[Level-1],NowID+' '+ShowTxt);
      MyNode[Level].ImageIndex:=1;
     MyNode[Level].SelectedIndex:=2;
    end;  
    //以上是增加子项
    Next;
    end;
    finally
    Close;
    end;
    end;
    MyNode[0].Expand(False);//将首节点展开
    Screen.Cursor:=crDefault;
    end;
    //以上函数将Code.db表中的科目代码和科目代码名称显示出来

    //下面函数的功能是返回一代码的级数,
    //参数sFormat传递科目代码结构;
    //参数sCode传递某一科目代码
    function tfrmbmzd.GetLevel
    (sFormat,sCode:String):Integer;
    var i,Level,iLen:Integer;
    begin
    Level:=-1;//如果代码不符合标准,则返回-1
    iLen:=0;
    if (sFormat<>'')and(sCode<>'')then
    for i:=1 to Length(sFormat) do
    begin
    iLen:=iLen+StrToInt(sFormat[i]);
    if Length(sCode)=iLen then
    begin
      Level:=i;
      Break;
    end;
    end;
    Result:=Level;
    end;

    procedure Tfrmbmzd.FormShow(Sender: TObject);
    begin

    if not frmdm.tabbm.active then frmdm.tabbm.Open;
    frmdm.tabbm.IndexFieldNames:='BUMENG_ID';
    //按字段aCode排序(不要漏掉)

    LoadCode(frmdm.tabbm);

    end;

    procedure Tfrmbmzd.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
    Action := caFree;
    end;

    procedure Tfrmbmzd.cmd_newClick(Sender: TObject);
    begin
    tvwcode.SetFocus ;
    if tvwcode.selected.AbsoluteIndex<>0 then
    begin
    cmd_delete.Enabled:=true;
    cmd_update.Enabled:=true;
    cmd_save.Enabled :=true;
    if not frmdm.tabbm.Active then frmdm.tabbm.Open;

    edit1.text:=frmdm.tabbm.Fields[0].asstring;
    end;
    tvwcode.SetFocus ;
    tvwcode.Items.AddChild(tvwcode.selected,'新建部门');
    if   tvwcode.Selected.HasChildren then
    begin
    if tvwcode.Selected.GetLastChild.index+1>9 then
     edit2.text:=inttostr(tvwcode.Selected.GetLastChild.index+1)
     else
    edit2.text:='0'+inttostr(tvwcode.Selected.GetLastChild.index+1);
    edit3.text:='新建部门';
    edit2.Enabled:=true;
    edit3.Enabled:=true;
    end
    else
    begin
    edit2.text:='01';
    edit3.text:='新建部门';
    edit2.Enabled:=true;
    edit3.Enabled:=true;
    end;
    if not frmdm.tabbm.Active then frmdm.tabbm.Open;
    frmdm.tabbm.edit;
    frmdm.tabbm.Append;
    cmd_new.Enabled :=false;
    cmd_delete.Enabled :=false;
    cmd_update.Enabled :=false;
    cmd_save.Enabled :=true;
    //新建下级部门

    tvwcode.Selected.GetLastChild.Selected:=true;
    //设选择
    tv:=tvwcode.Selected ;
    tvwcode.autoExpand:=true;
    tvwcode.SetFocus ;


    end;

    procedure Tfrmbmzd.cmd_deleteClick(Sender: TObject);
    var
    I:integer;
    seno,setext:string;
    begin
    if tvwcode.Selected.HasChildren=true then
    begin
    application.messagebox('该部门包含下级,不能删除','提示',MB_OKCANCEL+mb_iconquestion ) ;
    end
    else
    begin
    if   application.messagebox('你确实要删除当前部门吗','提示',MB_OKCANCEL+mb_iconquestion )=IDOK then
    begin
    setext:=tvwcode.selected.text;
    i:=0;
    while setext[i] <> ' ' do
    begin
    I := I + 1;
    seno:=seno+setext[i];
    end;
    if not frmdm.tabbm.Active then frmdm.tabbm.Open;
    frmdm.tabbm.setkey;
    frmdm.tabbm.Fields[0].asstring:=seno;
    if frmdm.tabbm.GotoKey then
    begin
    frmdm.tabbm.edit;
    frmdm.tabbm.Delete;
    end;
    tvwcode.Selected.Delete ;
    cmd_new.Enabled :=true;
    tvwcode.autoExpand:=true;
     tvwcode.SetFocus ;
    end;
    end;

    end;

    procedure Tfrmbmzd.Edit2KeyPress(Sender: TObject; var Key: Char);
    begin
    if key  in ['0'..'9',Chr(vk_Back)]   then

    else
    begin
    key:=#0;
    application.messagebox('','',mb_ok);

    end;
    end;

    procedure Tfrmbmzd.tvwcodeChange(Sender: TObject; Node: TTreeNode);
    var
    i,lev:integer ;
    strr,seno,setext:string;
    begin
    if cmd_new.Enabled =true then
    begin
    if tvwcode.selected.AbsoluteIndex<>0   then
    begin
    cmd_delete.Enabled:=true;
    cmd_update.Enabled:=true;
    cmd_save.Enabled :=true;
    setext:=tvwcode.selected.text;
    i:=0;
    while setext[i] <> ' ' do
    begin
    I := I + 1;
    seno:=seno+setext[i];
    end;
    if not frmdm.tabbm.Active then frmdm.tabbm.Open;
    frmdm.tabbm.setkey;
    frmdm.tabbm.Fields[0].asstring:=seno;
    frmdm.tabbm.GotoKey;
    strr:='';

    case tvwcode.Selected.Level of
    2: strr:=copy(frmdm.tabbm.fields[0].asstring,1,2);
    3: strr:=copy(frmdm.tabbm.fields[0].asstring,1,4);
     end;
     edit1.text:=strr;
    //加上级编码
    edit3.text:=frmdm.tabbm.Fields[1].asstring;
    //本级编码

    edit2.text:=copy(frmdm.tabbm.fields[0].asstring,length(frmdm.tabbm.fields[0].asstring)-1,2);

    end
    else
    begin
    edit1.text :='';
    edit2.text :='';
    edit3.text :='部门分类';
    cmd_delete.Enabled :=false;
    cmd_update.Enabled :=false;
    end;
    end;
    end;


    procedure Tfrmbmzd.cmd_updateClick(Sender: TObject);
    var
    i:integer;
    begin
    for i:=0 to ComponentCount-1  do
    begin
    if (Components[I]  is tedit ) then
    (Components[I]  as tedit).enabled:=false;
    end;
    for i:=0 to ComponentCount-1  do
    begin
    if (Components[I]  is tbitbtn ) then
    (Components[I]  as tbitbtn).enabled:=true;
    end;
    if tvwcode.Selected.AbsoluteIndex<>0 then
    begin

    if not frmdm.tabbm.Active  then frmdm.tabbm.Open;
    frmdm.tabbm.Edit;
    frmdm.tabbm.Fields[0].asstring:=edit1.text+edit2.text;
    frmdm.tabbm.Fields[1].asstring:=edit3.text;
    try
    frmdm.tabbm.Post;
    //表的保存
    except
    on edbengineerror do
    begin
    edit2.Enabled :=true;
     application.messagebox('编号不能重复,请重新输入','提示',MB_OK+mb_iconquestion ) ;
    exit;
    end;
     end;
    tvwcode.Selected.Text:=edit1.text+edit2.text+' '+edit3.text;
    tvwcode.SetFocus ;
    //修改树
    end;

    cmd_new.Enabled :=true;
    edit2.Enabled :=false;
    end;

    procedure Tfrmbmzd.BitBtn2Click(Sender: TObject);
    begin
    cmd_new.Enabled :=false;
    cmd_delete.Enabled :=false;
    edit2.enabled:=true;
    edit3.Enabled :=true;

    end;

    procedure Tfrmbmzd.tvwcodeClick(Sender: TObject);
    var
    i:integer;
    begin
    if cmd_new.Enabled =false then
    begin
    application.MessageBox('当前是修改状态,请单击保存按钮','提示',mb_ok);
    tv.Selected :=true;
    end;
    if  tvwcode.selected.AbsoluteIndex=0 then
    begin
    for i:=0 to ComponentCount-1  do
    begin
    if (Components[I]  is tedit ) then
    (Components[I]  as tedit).enabled:=false;
    end;
    for i:=0 to ComponentCount-1  do
    begin
    if (Components[I]  is tbitbtn ) then
    (Components[I]  as tbitbtn).enabled:=false;
    cmd_new.Enabled :=true;
    cmd_exit.Enabled :=true;
    end;
    end;
    end;
    end

    四、使用概述
    树形图(Treeview)是Win95下新增加的通用显示部件(Common Control,在COMCTL32.DLL中)之一,从Delphi2.0开始也增加了相应的控件Treeview,用于取代原Outline控件。由于树形图结构较复杂,使用起来常不知如何下手。这里就使用中的一些问题作些介绍。
       Treeview用于显示按照树形结构进行组织的数据,这在实际当中用途还是比较广泛的,如计算机中的文件系统(Windows95中的资源管理器)、企业或公司的组成结构等等。Treeview控件中一个树形图由节点(TreeNode)和连接线组成。TtreeNode是TTreeview的基本组成单元。一个树的节点又包含文本(Text)和数据(Data)。Text为String类,Data则为无定形指针(Untyped Pointer),可以指向一个与节点相联系的数据结构。
      每一个节点下子节点形成这一节点的Items属性,当前节点有一个唯一的Index(TreeNode的Index属性),用于说明子节点在Items中的位置,每一个节点下的子节点是顺序编号的,第一个是0,第二个是1,依次类推。用IndexOf方法获得子节点的顺序,绝对顺序(AbsoluteIndex)则是指从Treeview第一个项开始的顺序值,第一个是0,如此推下去。Item属性则根据Index的值返回当前节点的第Index个子节点。Count则表明属于此项的所有子节点的数量。用MoveTo方法将Item由一个位置移到另一个位置。
      Expanded属性表明是否所有的子项都全部展开(包括子项的子项),为True表示全部展开。IsVisible属性表明一个项是否在树中能被看到,如果树全部展开那么这个Item是肯定可以被看到。HasChildren属性表明一个项是否有子项。 GetFirstChild, GetLastChild, GetPrevChild, and GetNextChild分别返回当前项子项的第一个、最后一个和前一个、后一个项。GetNextSibling and GetPrevSibling则返回在同一Level下的下一个和上一个项。GetNextVisible and GetPrevVisible则返回能看得到的下一个和上一个项。如果一个节点有Parent,则HasAsParent方法返回True. Parent为当前项的父项。Focused属性确定焦点是否落在此节点上,被Focus时会一个标准的方框围住。很显然,只有一个节点会被聚焦。 Selected属性表明一个节点是否被选中,同样只有一个节点会被选中。DropTarget属性表明节点在拖动操作中是源还是目标。
    1.添加、删除、修改节点:
    静态的方法可以在设计时通过Items的编辑器设置各节点的内容。
    在添加和删除前必须保证有节点被选中(Treeview.Selected = nil)
    用AddFirst, AddFirstChild, AddChild等先添加根节点,如Treeview.Items.AddFirst( nil, 'Root');
    然后以此为基础,添加此项的子节点。

    删除节点
    Treeview.Selected.Delete
    编辑节点内容
    Treeview.Selected.EditText
    注意:由于根节点没有父节点 (TTreeNode.Parent= nil)
    此外,在大批量添加数据到Treeview中时最好使用
      TreeView.Items.BeginUpdate;
      添加节点
      TreeView.Items.EndUpdate
    这样能加快显示速度。

    2.在节点上添加图象
    Treeview中几个与图象相关的属性:
      SelectedIndex:当节点被选中时在TimageList 中选什么样的图象
      OverlayIndex:选那副图象作为掩图(一幅图象透明地显示在另一幅图象的前面),比如一个节点不可用时加一副X图象在其前面。
      ImageIndex:在常态时选用的图的序号
      StateIndex: 在StateImages这个ImageList中对应的序号,-1时不显示图象
      比较典型的,象在文件管理器中的所显示的一样,Treeview控件在节点之前也可以显示图象。在Form中放置一ImageList控件,加入几个图片,分别被Index为0,1,…在Treeview的Image属性项填入你所加入的ImageList的控件名称。TreeNode的ImageIndex表示节点未被选中时(Selected=nil)的图片序号,SelectedIndex表示节点被选中时图片序号。

    3.关于Level
    Level的概念可以用下图表示:
    Level0   Level1 Level2

    4.排序
    SortType决定什么时候进行排序;
    TreeView.AlphaSort对节点进行排序,如果不能满足要求,你可以定义自己的CustomSort方法。
    5.Drag&Drop操作,与标准的拖放操作使用方法一样。

    五、一个例子:
     首先,在库的构建上要有一定策略以下几个字段非常重要:
    'codeID'      代码集名称 (例如:'AB')
    'code'        节点代码   (例如:'新疆'节点的代码为'65','乌鲁木齐'的节点代码为'6501'等)
    'description' 节点描述   (例如:如上面的'新疆'、'乌鲁木齐'等)
    'pptr'        父节点代码(例如:'乌鲁木齐'节点的父代码为'65',最高层节点的父节点代码可同其代码集,例如:'新疆'的父节点为                              'AB')
    'cptr'        子节点标识 (例如:该节点是否有下级节点,有则取值'1',没有则取值'0')

    建立树由两部分构成:

    procedure TForm1.FormActivate(Sender: TObject);
    var
     code_ID,new_sql,node_text,table_name:string;
     new_node:Ttreenode;
    begin

    //要传递的参数
    code_ID:='AB';
    table_name:='sr_codeitem';

    //********
    treeview1.Items.BeginUpdate;

    //清空所有项目
    treeview1.Items.Clear;


    new_sql:='select * from '+ table_name + ' where codeID='+''''+code_ID+''''
            + ' and '+'pptr='+''''+code_ID+'''';


    //数据集中先筛选出所有要增加节点
    with dm1.Query1 do
    begin
      close;
      sql.Clear;
      sql.Add(new_sql);
      open;
      //增加第一层节点
      while not eof do
        begin
          node_text:=fieldbyname('code').asstring;
          node_text:=node_text+'   '+fieldbyname('description').asstring;
          new_node:=treeview1.Items.add(nil,node_text);
          new_node.HasChildren:=true;
          next;
        end;//end while
    end;//end with

    treeview1.Items.EndUpdate;
    end;

    procedure TForm1.TreeView1Expanding(Sender: TObject; Node: TTreeNode;
    var AllowExpansion: Boolean);
    var
     new_sql,node_text,child_text,code_ID,table_ID:string;
     child_node:Ttreenode;
    begin
    //获取参数
    code_ID:='AB';
    table_ID:='sr_codeitem';

    treeview1.Items.BeginUpdate;
    node_text:=node.Text;
    //截取所点击节点的code
    node_text:=copy(node_text,1,pos(' ',node_text)-1);
    with dm1.Query1 do
    begin
      close;
      sql.Clear;
      new_sql:='select * from '+table_ID+' where pptr='+''''+node_text+'''' + ' and codeID='
                +''''+code_ID+'''';
      sql.Add(new_sql);
      open;//定位所点的项
      //清除原来的下级节点
      node.DeleteChildren;
      while not eof do
         begin//增加下级节点
           child_text:=fieldbyname('code').asstring+'   '+fieldbyname('description').asstring;
           child_node:=treeview1.Items.AddChild(node,child_text);
           if fieldbyname('cptr').asstring='1' then
              child_node.HasChildren:=true;
              next;
         end;//end while

    end;//end with
    treeview1.Items.EndUpdate;
    end;
     第二部分:在 treeview 的onExpanding 事件中添加如下代码
    procedure TForm1.TreeView1Expanding(Sender: TObject; Node: TTreeNode;
    var AllowExpansion: Boolean);
    var
     new_sql,node_text,child_text,code_ID,table_ID:string;
     child_node:Ttreenode;
    begin
    //获取参数
    code_ID:='AB';
    table_ID:='sr_codeitem';

    treeview1.Items.BeginUpdate;
    node_text:=node.Text;
    //截取所点击节点的code
    node_text:=copy(node_text,1,pos(' ',node_text)-1);
    with dm1.Query1 do
    begin
      close;
      sql.Clear;
      new_sql:='select * from '+table_ID+' where pptr='+''''+node_text+'''' + ' and codeID='
                +''''+code_ID+'''';
      sql.Add(new_sql);
      open;//定位所点的项
      //清除原来的下级节点
      node.DeleteChildren;
      while not eof do
         begin//增加下级节点
           child_text:=fieldbyname('code').asstring+'   '+fieldbyname('description').asstring;
           child_node:=treeview1.Items.AddChild(node,child_text);
           if fieldbyname('cptr').asstring='1' then
              child_node.HasChildren:=true;
              next;
         end;//end while

    end;//end with
    treeview1.Items.EndUpdate;
    end; 

    六、让我们一个一个来回答:
    第一个:取出节点的text属性值,赋给Richedit的Lines.text即可;
    例如: self.RichEdit1.Lines.text:= self.Treeview1.selected.text;
    第二个:TtreeView控件有函数保存和载入树的结构到文件
    例如:self.Treeview1.SaveToFile('文件名');//保存结构
         self.TreeView1.LoadFromFile('文件名');//载入结构
    第三个:TreeView的每个节点都有ItemID(句柄),AbsoluteIndex(相对于树头节点的索引位置),
    Index(在当前层的位置),Level(本节点的层数)通过访问这些可以知道其位置;
    例如:self.TtreeView1.selected.ItemID;//返回句柄
        self.TreeView1.selected.Level;//返回层数
        self.TreeView1.Items.count//返回所有节点的个数;
    **寻找某一个节点的话,就只有写一个循环来遍历整个树,直到找到符合条件的节点为止,
    关于查找节点的代码我也在想,先参考上面同志们的回答吧;

    ??**为某个节点加上子节点,例如:
    var NewNode:TTreeNode;
    begin
    NewNode:=self.Treeview1.Items.addChild(self.Treeview1.Items[3],'新的字节点');
    //为self.Treeview1.Items[3]加上一个字节点,标签是'新的字节点',
    //还有其他的ADD方法,可以查找Delphi帮助
    //然后可以给刚加上去的子节点赋值;
    NewNode.ImageIndex:=n;
    NewNode.SelectedIndex:=M;
    NewNode.Data:=X;//注意X是一个指针类型;关于这方面的帮助
    //可以找一下TTreeNode.Data 属性例子
    end;
    ??**想选中某个节点:self.TreeView1.Items[n].selected:=true;//这样就选中了
    ??**展开某节点就容易了:self.TreeView1.Items[n].Expand;//展开啦!
    //想合上就用Collapse(Recurse: Boolean)函数,
    总之呢,去查一下TtreeNode的帮助吧!
    ??**清除某节点下的所有子节点,用DeleteChildren是没错的,例如:
    self.Treeview1.Items[n].DeleteChildren;//OK,下面都没了!

    七、query1.close;
    query1.sql.clear;
    query1.sql.add('select * from t08 order by t0801');
    try
      query1.open;
    except
      on e:exception do
      begin
         application.MessageBox(pchar('打开数据库文件失败!'+#13+#13+e.Message),'错误信息',16);
         close;
         exit;
      end;
    end;
    //创建结构树
    while not query1.eof do
    begin
       s:=trim(query1.fields[0].asstring);
       case length(s) of
       2:begin
            tv1.Selected:=tv1.items.add(nil,trim(query1.fields[1].asstring));
            tv2.Selected:=tv2.items.add(nil,trim(query1.fields[0].asstring));
         end;
       4:begin
            p1:=tv1.items.addchild(tv1.Selected,trim(query1.fields[1].asstring));
            p2:=tv2.items.addchild(tv2.Selected,trim(query1.fields[0].asstring));
         end;
       6:begin
            tv1.Items.addchild(p1,trim(query1.fields[1].asstring));
            tv2.Items.addchild(p2,trim(query1.fields[0].asstring));
         end;
       end;
       query1.next;
    end;
    query1.close;
    if tv1.Items.Count>0 then
    begin
     tv1.Selected:=tv1.Items[0];
     tv1.Selected.Expand(true);
    end;
    tv1.OnClick(self); 
    八、clear速度慢的问题
     问题的关键在于Clear方法会一个一个地删除每个Node,
    于是TreeView不断刷新,所以速度就....
    代码修正一下:
    with MyTreeView.Items do
    <B>try</B>
    BeginUpdate;
    Clear;
    <B>finally</B>
    EndUpdate;
    <B>end;</B>

    另外
    1、你现在遇到的问题是大量删除,
    如果是大量插入,也应该同样处理
    2、ListView有同样问题,注意
    其他Windows控件也有,但不很明显
    比如Memo、RichEdit等等
    总之,凡大量数据修改的情况下,
    应该注意BeginUpdate和EndUpdate
    3、<B>BeginUpdate和EndUpdate应该一一对应</B>,
    因为Delphi实际上是用<B>计数器</B>来处理的,
    如果忘了EndUpdate,
    或者BeginUpdate比EndUpdate次数多,
    可能导致控件不刷新了

    九、用treeview做权限管理

  • 相关阅读:
    linux command mktemp
    易经中时常会想起的句子
    判断NumLock键和CapsLock键是否被锁定
    获得虚拟键键码
    获取功能键
    捕获组合键
    模拟鼠标操作
    利用鼠标绘图
    使用鼠标拖放复制文本
    双击窗体是模拟键盘上的Tab键
  • 原文地址:https://www.cnblogs.com/zcm123/p/2857353.html
Copyright © 2020-2023  润新知