Delphi中dxTreelist控件的使用

来源:互联网 发布:节奏大师挂软件 编辑:程序博客网 时间:2024/05/20 05:30

    最近公司项目中用到dxTreelist控件,以前没怎么用过这个控件,该控件比TreeView功能更强大,要完全掌握还真不容易,下面是我个人做的一个Demo,对该控件进行增删改遍历操作,以便自己以后忘了使用方法随时可以查吧。

1.首先新建一个数据库。

     打开SQL Server2005,新建数据库TreeTest,新建表DeviceTab,表的字段设计如下:

      

 

2.新建Delphi应用程序

   选择File-New-Application新建应用程序,File-New-Data Module,新建一个数据库模块,添加TADOConnection和TImageList控件,设置ADOConnection的LoginPrompt为false,给ImageList控件添加7个图片,该数据模块的Create事件代码如下:

    procedure Tdm.DataModuleCreate(Sender: TObject);

        begin
          if not con1.Connected then
         begin
         //设置连接字符串
    con1.ConnectionString:='Provider=SQLOLEDB.1;Password=123456;Persist Security Info=True;User ID=sa;Initial Catalog=TreeList;Data Source=ZH\SQLEXPRESS;';
          con1.Open; //打开数据库连接
         end;
        end;

  

   在窗体上放置dxTreeList控件和四个Button控件以及一个Timer控件设置Timer控件的Interval属性为100,各按钮相关事件及源码如下:

unit Main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, dxExEdtr, dxCntner, dxTL, dxTLClms,ADODB, Menus,
  cxLookAndFeelPainters, StdCtrls, cxButtons, ExtCtrls;

type
  TfrmTree = class(TForm)
    dxTreeList1: TdxTreeList;
    btnAddNode: TcxButton;
    btnDelNode: TcxButton;
    btnUpdate: TcxButton;
    btnbl: TcxButton;
    tmr1: TTimer;
    procedure btnblClick(Sender: TObject);
    procedure btnAddNodeClick(Sender: TObject);
    procedure btnDelNodeClick(Sender: TObject);
    procedure btnUpdateClick(Sender: TObject);
    procedure tmr1Timer(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure CreateColumn(tree:TdxTreeList;list:TStrings);
    procedure CreateImageColumn(tree:TdxTreeList;Image:TImageList);
    procedure FillTree(node:TdxTreeListNode;pid:Integer;con:TADOConnection);
    function  GetMaxId(con:TADOConnection):Integer;
    procedure DelTree(pid:Integer;con:TADOConnection);
    procedure UpdateTree(newname:string;id:Integer;con:TADOConnection);
    function  GetCount(tree:TdxTreeList):Integer;
  end;

var
  frmTree: TfrmTree;

implementation

{$R *.dfm}

uses unitDM;

var
  list:TStrings;

procedure  TfrmTree.CreateColumn(tree:TdxTreeList;list:TStrings);  //动态创建dxTreeList的列
var
  i:Integer;
  col:TdxTreeListColumn;
begin
  for i:=0 to list.Count-1 do
   begin
     col:=tree.CreateColumn(TdxTreeListMaskColumn);
     col.Caption:=list[i];  //显示标题
     col.ColIndex:=i;      //列索引
     col.Name:=list[i];   //列标识
     col.Width:=90+10*i; //列宽
   end;
end;

procedure TfrmTree.CreateImageColumn(tree:TdxTreeList;Image:TImageList);//创建带图片的列
var
  col:TdxTreeListColumn;
  i:Integer;
begin
  col:=tree.CreateColumn(TdxTreeListImageColumn);
  col.Width:=50;
  col.Name:='img';
  TdxTreeListImageColumn(col).Images:=Image;
  for i:=0 to image.Count-1 do                //关联图片
   begin
     TdxTreeListImageColumn(col).ImageIndexes.Add(IntToStr(i));
     TdxTreeListImageColumn(col).Values.Add(IntToStr(i));
   end;
end;

procedure TfrmTree.FillTree(node: TdxTreeListNode; pid: Integer;con:TADOConnection);//构造树
var
  tmpnode:TdxTreeListNode;
  ADOQuery:TADOQuery;
begin
  ADOQuery:=TADOQuery.Create(nil);
  try
    ADOQuery.Connection:=con;
    ADOQuery.Close;
    ADOQuery.SQL.Clear;
    ADOQuery.SQL.Text:='select * from DeviceTab where pid='+Inttostr(pid);
    ADOQuery.Open;
    with ADOQuery do
     begin
       First;
       while not Eof do
        begin
          if node=nil then
             tmpnode:=dxTreeList1.Add //添加根节点
          else
             tmpnode:=node.AddChild;  //添加子节点
          pid:=FieldByName('id').AsInteger;
          tmpnode.Strings[0]:=IntToStr(pid);
          tmpnode.Strings[1]:=FieldByName('pid').AsString;
          tmpnode.Strings[2]:=FieldByName('aName').AsString;
          tmpnode.Strings[3]:=IntToStr(tmpnode.Level);
          tmpnode.ImageIndex:=tmpnode.Level;
          tmpnode.SelectedIndex:=tmpnode.Level;
          FillTree(tmpnode,pid,con);   //递归添加子节点
          Next;
        end;
     end;
  finally
    ADOQuery.Free;
  end;
end;

procedure TfrmTree.btnblClick(Sender: TObject); //遍历子节点
var
  node,tmpnode:TdxTreeListNode;
  i:Integer;
  str:string;
begin
  if dxTreeList1.Count=0 then Exit;
  node:=dxTreeList1.FocusedNode;  //获取焦点的节点
  for i:=0 to dxTreeList1.ColumnCount-1 do
    str:=str+node.Strings[i]+';';
    ShowMessage(str);
  tmpnode:=node.GetFirstChild;   //获取第一个子节点
  while tmpnode<>nil do
   begin
      str:=';
      for i:=0 to dxTreeList1.ColumnCount-1 do
        str:=str+tmpnode.Strings[i]+';';
      ShowMessage(str);
      //if tmpnode=node.GetLastChild then break;  

      if (tmpnode=node.GetLastChild) and (not tmpNode.HasChildren) then break;  //判断是否为最后一个子节点是终止循环
      tmpnode:=tmpnode.GetNext;  //获取下一个节点
   end;
end;

procedure TfrmTree.btnAddNodeClick(Sender: TObject);  //添加节点
var
  node:TdxTreeListNode;
  i:Integer;
  idindex,pidIndex,anameindex,imgIndex:Integer;
  id,pid:integer;
  aname:string;
  qry:TADOQuery;
  IsExist:Boolean;
begin
  aname:=';
  pid:=0;
  for i:=0 to dxTreeList1.ColumnCount-1 do
      begin
        if dxTreeList1.Columns[i].Name='aName' then
          begin
           anameindex:=i;
          end
        else if dxTreeList1.Columns[i].Name='id' then
          begin
           idindex:=i;
          end
        else if dxTreeList1.Columns[i].Name='pid' then
          begin
            pidIndex:=i;
          end
        else if dxTreeList1.Columns[i].Name='img' then
          begin
            imgIndex:=i;
          end;
      end;
  if InputQuery('添加节点','请输入节点名称',aname) then
   begin
     if dxTreeList1.Count=0 then
      begin
        node:=dxTreeList1.Add;      //添加根节点
      end
     else
       begin
         node:=dxTreeList1.FocusedNode; 
         if node.Level=6 then
          begin
            ShowMessage('已经添加到节点极限');
            exit;
          end;
         pid:=StrToIntDef(node.Strings[idindex],0);
         node:=node.AddChild;   //添加子节点
       end;

       id:=GetMaxId(dm.con1)+1;
       node.Strings[idindex]:=IntToStr(id);
       node.Strings[pidIndex]:=IntToStr(pid);
       node.Strings[anameindex]:=aname;
       node.Strings[imgIndex]:=IntToStr(node.Level);
       node.ImageIndex:=node.Level;
       node.SelectedIndex:=node.Level;
    try
      qry:=TADOQuery.Create(nil);
      qry.Connection:=dm.con1;
      qry.Close;
      qry.SQL.Clear;
      qry.SQL.Text:='insert into DeviceTab values('+inttostr(id)+','+Inttostr(pid)+','+QuotedStr(aname)+')';
      qry.ExecSQL;
    finally
      qry.Free;
    end;
   end;
end;

function TfrmTree.GetMaxId(con: TADOConnection): Integer; //获取最大ID值
var
  qry:TADOQuery;
begin
  try
    qry:=TADOQuery.Create(nil);
    qry.Connection:=con;
    with qry do
     begin
       close;
       sql.Clear;
       SQL.Add('select Max(id) as mid from DeviceTab');
       Open;
       First;
       Result:=qry.FieldByName('mid').AsInteger;
     end;
  finally
    qry.Free;
  end;  
end;

procedure TfrmTree.btnDelNodeClick(Sender: TObject); //删除节点
var
  node:TdxTreeListNode;
  i,aid:integer;
begin
  if dxTreeList1.Count=0 then
   begin
     ShowMessage('没有要删除的节点');
     Exit;
   end
  else
   begin
     node:=dxTreeList1.FocusedNode;
     if MessageBox(Self.Handle,PChar('确定要删除该节点及其所有的子节点吗?'),PChar('删除提示'),MB_OKCANCEL)<>IdOK then Exit;
     if node.HasChildren then node.DeleteChildren;  //删除子节点
     for i:=0 to dxTreeList1.ColumnCount-1 do
      begin
        if dxTreeList1.Columns[i].Name='id' then
          begin
           aid:=i;
           Break;
          end
      end;
     DelTree(StrToIntDef(node.Strings[aid],0),dm.con1);
     node.Free;
   end;
end;

procedure TfrmTree.DelTree(pid: Integer;con: TADOConnection); //删除数据库节点记录
var
  tmpnode:TdxTreeListNode;
  ADOQuery:TADOQuery;
begin
  ADOQuery:=TADOQuery.Create(nil);
  try
    ADOQuery.Connection:=con;
    with ADOQuery do
     begin
       Close;
       SQL.Clear;
       SQL.Text:='delete from DeviceTab where id='+Inttostr(pid);   //删除当前节点记录
       ExecSQL;
     end;
    ADOQuery.Close;
    ADOQuery.SQL.Clear;
    ADOQuery.SQL.Text:='select * from DeviceTab where pid='+Inttostr(pid);   //查找子节点记录
    ADOQuery.Open;
    with ADOQuery do
     begin
       First;
       while not Eof do
        begin
          DelTree(FieldByName('id').AsInteger,con);  //递归删除下级记录
          Next;
        end;
     end;
  finally
    ADOQuery.Free;
  end;
end;

procedure TfrmTree.btnUpdateClick(Sender: TObject);  修改
var
  node:TdxTreeListNode;
  aname:string;
  i,j,k,id:Integer;
  IsExist:Boolean;
begin
  IsExist:=False;
  if dxTreeList1.Count=0 then
    begin
      ShowMessage('没有要修改的节点');
      exit;
    end
  else
    begin
      dxTreeList1.BeginUpdate;
      node:=dxTreeList1.FocusedNode;
      for i:=0 to dxTreeList1.ColumnCount-1 do
      begin
        if dxTreeList1.Columns[i].Name='aName' then
          begin
           j:=i;
           aname:=node.Strings[i];
           Break;
          end
        else if dxTreeList1.Columns[i].Name='id' then
          begin
           k:=i;
           id:=StrToIntDef(node.Strings[i],0);
          end;
      end;
      if InputQuery('修改节点','请输入修改后的节点名',aname) then
        begin
              node.Strings[j]:=aname;
              UpdateTree(aname,id,dm.con1);//更新数据库记录
        end;
    end;
      dxTreeList1.EndUpdate;
end;

procedure TfrmTree.UpdateTree(newname: string; id: Integer;
  con: TADOConnection);
var
  qry:TADOQuery;
begin
  qry :=TADOQuery.Create(nil);
  try
    with qry do
     begin
       Connection:=con;
       Close;
       SQL.Clear;
       SQL.Text:='update DeviceTab set aname='+Quotedstr(newname)+'   where id='+Inttostr(id);
       ExecSQL;
     end;
  finally
    qry.Free;
  end;

end;

procedure TfrmTree.tmr1Timer(Sender: TObject); 
begin
  tmr1.Enabled:=False;
  list:=TStringList.Create;
  dm.con1.GetFieldNames('DeviceTab',list); //获取表的字段名
  CreateColumn(dxTreeList1,list);
  CreateImageColumn(dxTreeList1,dm.il1);
  dxTreeList1.BeginUpdate;
  FillTree(nil,0,dm.con1);
  dxTreeList1.EndUpdate;
end;

procedure TfrmTree.FormDestroy(Sender: TObject);
begin
  list.Free;
  if dm.con1.Connected then
    dm.con1.Close;
end;

function TFrmTree.GetCount(tree:TdxTreeList):integer;  //获取总的节点数
var
  node:TdxTreeListNode;
begin
  Result:=0;
  dxTreeList1.GotoFirst;
  node:=dxTreeList1.Items[0];
  while node<>nil do
   begin
     inc(Result);
     node:=node.GetNext;
   end;
end;

end.

 

3.运行效果

   初始界面

 

添加节点后界面

 

删除节点后界面

 

修改节点后界面

 

节点遍历( 部分截图)

 

 

  

   总结:dxTreelist控件的属性和方法还有许多,功能比TreeView更丰富,同时操作也更复杂,它没有treeview.items.count属性获取节点总数,它的每一个节点都是一个TdxTreeListNode节点,操作每个节点时用Strings或Values集合来赋值给节点的每一列,以后如果用到再深入研究一下,这个Demo足够一般的应用。

 

 

原创粉丝点击