如何实现带有checkbox的ttreeviw,我是想做个类似瑞兴杀毒的那个操作界面。

解决方案 »

  1.   

    有个想法,当点击节点就可以把它的图标可以修改,是否选中的信息可以保存在节点的
    TTreeNode.Data作为是否选中的信息。
      

  2.   

    你可以把这些数据写入一个表,关于怎么选中,可以在ONDblClick里写
      

  3.   

    使用check.gif和uncheck.gif两张图片作为每个结点的image,在treeview的onclick事件中根据当前所选的node,将该node的image属性在check.gif与uncheck.gif间切换
      

  4.   

    那样操作不方便的,我只要 onclick 应该能完成该任务的吧
      

  5.   

    听了你说的,我在现在的项目里做了这样的东西,显示很正确。代码如下:unit gz_setup;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      ChildFrm, ImgList, ComCtrls, ExtCtrls, CodeTreeView, Db, DBTables;type
      Tfrm_gz_setup = class(TChildForm)
        Panel1: TPanel;
        StatusBar1: TStatusBar;
        ImageList1: TImageList;
        TreeView1: TTreeView;
        Query1: TQuery;
        Panel2: TPanel;
        procedure FormCreate(Sender: TObject);
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
        procedure TreeView1CustomDrawItem(Sender: TCustomTreeView;
          Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
        procedure TreeView1DblClick(Sender: TObject);
      private
        { Private declarations }
        one_level,two_level:array of string;
        procedure CreateTree;  public
        { Public declarations }
      end;var
      frm_gz_setup: Tfrm_gz_setup;implementation
     uses pub_tree, dm_sbgl,publicVar;
    {$R *.DFM}procedure Tfrm_gz_setup.FormCreate(Sender: TObject);
    Var code ,Text : string;
    begin
      inherited;
      CreateTree;
    end;procedure Tfrm_gz_setup.FormClose(Sender: TObject;
      var Action: TCloseAction);
    begin
      inherited;
      frm_gz_setup:=nil;
    end;procedure Tfrm_gz_setup.CreateTree;
    var
      tt,querysql:string;
      tmp,c,d:TTreeNode;
      i:integer;
    begin
      i:=0;
      tmp:=TreeView1.Items.AddChild(nil,'工种目录');
      tt:='select a.gzbh,a.gzmc,b.gzbh cc from RDGZML a,SB_MAN_GZ b where '
         +' length(a.gzbh)=2 and a.gzbh=b.gzbh(+)';
      OpenSql(Query1,tt);  SetLength(one_level,Query1.RecordCount);  while Not Query1.Eof do
      begin
        c:=TreeView1.Items.AddChild(tmp,Query1.FieldByname('gzmc').AsString);
        if Query1.FieldByName('cc').AsString='' then
        begin
           c.SelectedIndex:=2;
           c.ImageIndex:=2;
        end else
        begin
           c.ImageIndex:=1;
           c.SelectedIndex:=1;
        end;
        one_level[i]:=Query1.FieldByName('gzbh').AsString;
        c.Data:=Pointer(one_level[i]);
        i:=i+1;
        Query1.Next;
      end;  querysql:= 'select a.gzbh,a.gzmc,b.gzbh cc from RDGZML a,SB_MAN_GZ b where '
         +' length(a.gzbh)=4 and a.gzbh=b.gzbh(+) and substr(a.gzbh,1,2)=''%s''';  tt:='select gzbh from rdgzml where length(gzbh)=4';
      OpenSql(query1,tt);
      SetLength(two_level,Query1.RecordCount);  i:=0;
      c:=tmp.getFirstChild;
      if c=nil then exit;  tt:=Format(querysql,[String(c.data)]);
      OpenSql(Query1,tt);
      while not Query1.Eof do
      begin
        d:=TreeView1.Items.AddChild(c,Query1.FieldByname('gzmc').AsString);
        if Query1.FieldByName('cc').AsString='' then
        begin
           d.SelectedIndex:=2;
           d.ImageIndex:=2;
        end else
        begin
           d.ImageIndex:=1;
           d.SelectedIndex:=1;
        end;
        two_level[i]:=Query1.FieldByName('gzbh').AsString;
        d.Data:=Pointer(two_level[i]);
        i:=i+1;
        Query1.Next;
      end;
      c:=tmp.GetNextChild(c);
      while c<>nil do
      begin
        tt:=Format(querysql,[String(c.data)]);
        OpenSql(Query1,tt);
        while not Query1.Eof do
        begin
          d:=TreeView1.Items.AddChild(c,Query1.FieldByname('gzmc').AsString);
          if Query1.FieldByName('cc').AsString='' then
          begin
            d.SelectedIndex:=2;
            d.ImageIndex:=2;
          end else
          begin
            d.ImageIndex:=1;
            d.SelectedIndex:=1;
          end;
          two_level[i]:=Query1.FieldByName('gzbh').AsString;
          d.Data:=Pointer(two_level[i]);
          i:=i+1;
          Query1.Next;
        end;
        c:=tmp.GetNextChild(c);
      end;
    end;procedure Tfrm_gz_setup.TreeView1CustomDrawItem(Sender: TCustomTreeView;
      Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
    var
      i:integer;
      tt:string;
    begin
      inherited;
      {if node.Level<>0 then
      begin
        tt:=string(node.data);
        Query1.Close;
        Query1.Sql.Text:='select gzbh from SB_MAN_GZ where gzbh='''+tt+'''';
        Query1.Open;
        if Query1.FieldByName('gzbh').AsString='' then
           Node.ImageIndex:=2
        else
           Node.ImageIndex:=1;
      end; }
    end;procedure Tfrm_gz_setup.TreeView1DblClick(Sender: TObject);
    var
      gzbh,tt:string;
      Node,c:TTreeNode;
    begin
      inherited;
      Node:= TreeView1.Selected;
      if Node=nil then exit;
      if Node.Level=1 then
      begin
        gzbh:=string(Node.data);
        if Node.ImageIndex=1 then //表示开始选择,现在去掉
        begin
          tt:='delete from SB_MAN_GZ where gzbh like'''+gzbh+'%''';
          ExecSqlEX(tt);
          Node.ImageIndex:=2;
          Node.SelectedIndex:=2;
          c:=Node.getFirstChild;
          if c=nil then exit;
          c.ImageIndex:=2;
          c.SelectedIndex:=2;
          c:=Node.GetNextChild(c);
          while c<>NIl do
          begin
            c.ImageIndex:=2;
            c.SelectedIndex:=2;
            c:=Node.GetNextChild(c)
          end;
        end else  //没有选择,现在增加
        begin
          tt:='insert into  SB_MAN_GZ select gzbh from rdgzml where gzbh like '''+gzbh+'%'''
             +' and gzbh not in (select gzbh from SB_MAN_GZ)';
          ExecSqlEX(tt);      Node.ImageIndex:=1;
          Node.SelectedIndex:=1;      c:=Node.getFirstChild;
          if c=nil then exit;
          c.ImageIndex:=1;
          c.SelectedIndex:=1;
          c:=Node.GetNextChild(c);
          while c<>NIl do
          begin
            c.ImageIndex:=1;
            c.SelectedIndex:=1;
            c:=Node.GetNextChild(c)
          end;
        end;
      end;  if Node.Level=2 then
      begin
        gzbh:=string(Node.data);
        if Node.ImageIndex=1 then //表示开始选择,现在去掉
        begin
          tt:='delete from SB_MAN_GZ where gzbh='''+gzbh+'''';
          ExecSqlEX(tt);
          Node.ImageIndex:=2;
          Node.SelectedIndex:=2;
        end else  //没有选择,现在增加
        begin
          tt:='select gzbh from SB_MAN_GZ where gzbh='''+gzbh+'''';
          OpenSql(Query1,tt);
          if Query1.FieldByName('gzbh').AsString='' then
          begin
            tt:='insert into  SB_MAN_GZ values('''+gzbh+''')';
            ExecSqlEX(tt);
          end;
          Node.ImageIndex:=1;
          Node.SelectedIndex:=1;
        end;
      end;
    end;end.
      

  6.   

    用节点Image控制选择状态,很好控制!同意!tw_cshn(一无所有)
      

  7.   

    我到做了一个,在公司,现在在家,代码也没办法发给你,你要的话留下你的信箱,主要是用stateimage属性,只有它不会在选择的时候,不会跟字以前选择
      

  8.   

    一无所知 仁兄:
    请你给出SetLength,  OpenSql的实现代码!谢谢!
      

  9.   

    SetLength就是DELPHI自带的,OPENSQL就是打开一个QUERY
      

  10.   

    用第三方构件不可以吗。1stclass3000 for delphi6去 www.51delphi.com 去找啊
      

  11.   

    var
      Add_group: TAdd_group;
      Cur_Left,Cur_Top,Cur_Right,Cur_Bottom:Integer;
      Cur_Node,Old_Node:TTreeNode;
      Cur_StateIndex:Integer;
      G_GroupID:Integer;
    //上面是定义的全局变量 procedure TAdd_group.tBSW_treeView1Change(Sender: TObject;
      Node: TTreeNode);
    begin
      Cur_Node := Node;
      Cur_Left := Node.DisplayRect(True).Left;
      Cur_Top := Node.DisplayRect(True).Top;
      Cur_Right := Node.DisplayRect(True).Right;
      Cur_Bottom := Node.DisplayRect(True).Bottom;
      Cur_StateIndex := Node.StateIndex;
    end;procedure TAdd_group.tBSW_treeView1MouseDown(Sender: TObject;
      Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    var
      Parent_Node,Pri_Node:TTreeNode;
      i_loop :integer;
      i_Sum:integer;
    begin
      if (X>Cur_Left -16) and (X <Cur_Left) and (Y >Cur_Top) and (Y<Cur_Top+ 16) then
        begin
          if Cur_Node.HasChildren then
            begin
              //设置状态
              if Cur_Node.StateIndex = 1 then
                Cur_Node.StateIndex := 2
              else
                Cur_Node.StateIndex := 1;
              Cur_StateIndex := Cur_Node.StateIndex;
             //////////
             Pri_Node := Cur_Node.getFirstChild;
             Pri_Node.StateIndex := Cur_StateIndex;
             for i_loop := 1 to Cur_Node.Count -1  do
               begin
                 Pri_Node := Pri_Node.GetNext;
                 Pri_Node.StateIndex := Cur_StateIndex;
               end;        end
          else
            begin
              if Cur_Node.StateIndex = 1 then
                Cur_Node.StateIndex := 2
              else
                Cur_Node.StateIndex := 1;
              Cur_StateIndex := Cur_Node.StateIndex;
              try
                Parent_Node := Cur_Node.Parent;
                i_Sum := 0;
                Pri_Node := Parent_Node.getFirstChild;
                if Pri_Node.StateIndex = 2 then i_Sum := i_Sum + 1;
                for i_loop := 1 to Parent_Node.Count -1 do
                  begin
                    Pri_Node := Pri_Node.GetNext;
                    if Pri_Node.StateIndex = 2 then i_Sum := i_Sum + 1;
                  end;
                if i_Sum = Parent_Node.Count then
                  Parent_Node.StateIndex := 2
                else
                  if i_Sum = 0 then
                    Parent_Node.StateIndex := 1
                   else
                     Parent_Node.StateIndex := 3;
              except
              end;
            end;
          Old_Node.Selected := True;
          exit;
        end;
      if (x>Cur_left) and (x<Cur_right) and (y>Cur_top) and (y<Cur_Bottom) then
         Old_Node := Cur_Node;end;在Change的时候记录信息,在MouseDown的时候判断鼠标点在字上还是前面的图片做的复选框
    图片1是空的,图片2是代表全选了,图片3代表子节点中至少有一个没选,这个是操作的时候的代码,初始化的代码如果要的话,我也可以发给你看
      

  12.   

    treeviw的Images属性设定为空,而StateImages设为ImageList1然后加入你选的图片,总共要加四副图片,第一幅也就是编号为0随便,后面编号为1,2,3的依次是没有选种状态的图片,选中状态的图片,和子节点至少有一个没有选中的图片
      

  13.   

    你们的水平真高!不过好像很累...要我,就去抓一个具有这种功能的控件,像express的或是1st class3000
      

  14.   

    乱掉是因为 selectIndex没有设置,正确方法是:imageindex和selectIndex都要一致
      

  15.   

    [email protected]
    谢谢!
    急用