如何实现treeview与数据库的连接,实现读写操作????

解决方案 »

  1.   

    TREEVIEW不能直接和数据库连接
    可以通过数据库连接组件,动态从数据库中读取数据,当然也可以通过他来保存数据.
    adoquery.sql:='select  * from table'
    adoquery.open;
    treeview.items.add(node,adoquery.fields[0].asstring);
      

  2.   

    好像有这样的第3方控件,上51delphi上找找,或者
    自己写代码,将需要显示的字段添加到treeview中,下面的代码是我写的一个程序中的,
    也不知道是否能够看明白,你自己慢慢看吧
    //功能:根据SysDb表中的记录装载光盘目录到treeview中
    //参数:无
    //返回值:无
    procedure TFrmMain.LoadGPTreeView();
    var
      strGP:String;
      i,nCount,nid:Integer;
      Node: TTreeNode;
      Nodetemp: TTreeNode;
      MyRecPtr: PMyRec;begin
      try
        spSkinGauge1.Visible :=true;
        spSkinGauge1.Value :=0;
        Screen.Cursor := crHourGlass;
        TreeView1.Items.Clear;
        TreeView1.Items.AddFirst(nil,ReadStr(13));//'光盘管家'
        spSkinGauge1.Value:=spSkinGauge1.Value+1;
        spSkinGauge1.ProgressText :=ReadStr(27);   //'请稍候... '
        Node:=TreeView1.Items.Item[0];    Node.ImageIndex := 0;
        DataMod.ADOtemp.Active :=false;
        DataMod.ADOtemp.Connection := DataMod.ADOConnection1;
        DataMod.ADOtemp.SQL.Clear;
        DataMod.ADOtemp.SQL.Add('Select * from SysDB');
        DataMod.ADOtemp.Open;    if DataMod.ADOtemp.RecordCount >0 then
        begin
          nCount:=DataMod.ADOtemp.RecordCount;
          DataMod.ADOtemp.First;
          for i:=0 to nCount-1 do
          begin
            if g_bCloseApp then exit;
            New(MyRecPtr); //分配内存
            MyRecPtr^.id := 0;
            MyRecPtr^.pid := -1;
            MyRecPtr^.strGPName:= DataMod.ADOtemp.FieldByName('CdNo').AsString;
            spSkinGauge1.Value:=spSkinGauge1.Value+1;
            strGP:= DataMod.ADOtemp.FieldByName('Name').AsString;
            Nodetemp:=Treeview1.Items.AddChild(Node,strGP);
            Nodetemp.Data := MyRecPtr;
            Nodetemp.ImageIndex :=1;
            Nodetemp.SelectedIndex :=1;
           // if not LoadDirTreeView(strGP,TreeView1) then//指定的表不存在
           // DataMod.ADOtemp.Delete;
            DataMod.ADOtemp.Next;
          end;
        end
        else
        begin
           //当系统表中没有表名时先添加表名到sysdb中,再 LoadGPTreeView
           //出现把sysdb清空的现象,现在还没有找出原因2003.3.12
           if AddTableNameToSysdb() then
               LoadGPTreeView();
        end;
      finally
        DataMod.ADOtemp.Active :=false;
        spSkinGauge1.Visible :=false;
        Screen.Cursor := crDefault;
      end;
    end;
    //功能:从指定的表中装载目录到treeview中
    //参数:strTableName表名   mTreeView 是装载到指定的Treeview控件
    //返回值:打开表不成功,或者装载过程出错则返回false,否则返回true
    function TFrmMain.LoadDirTreeView(strTableName:String;mTreeView:TspSkinTreeView):boolean;
    var
      i,j:integer;
      lid,lpid,nGpBeginIndex:Longint;
      strDirectory:String;
      Nodep: TTreeNode;
      Node: TTreeNode;
      MyRecPtr: PMyRec;
      Nodetemp: TTreeNode;
      ADOSubtemp:TADOQuery;begin
    //在调用此函数前必须先添加一个level=1 text= strTableName 的结点
    //否则会出错。
      spSkinGauge1.Visible :=true;
      spSkinGauge1.Value :=0;
      Screen.Cursor := crHourGlass;
      spSkinGauge1.ProgressText :=ReadStr(27);//'请稍候... '
      nGpBeginIndex:=2;    //索引号从2开始才是文件夹 0是光盘管家,1则是第1个光盘的名称
      for i:=0 to mTreeView.Items.Count-1 do
      begin
        if g_bCloseApp then exit;
        Nodep:= mTreeView.Items[i];
        if Nodep.Level =1 then // Level=1 才是光盘名
        begin
          if (LowerCase(Nodep.Text) =LowerCase(strTableName)) then
          begin  //得到光盘的结点,因为可能会添加很多光盘
            Nodep:= mTreeView.Items[i];
             //得到光盘的起始索引号
            nGpBeginIndex:=Nodep.AbsoluteIndex;
            if Nodep.HasChildren then
            begin
               Nodep.DeleteChildren;
            end;
            break;
          end;
        end;
      end;  try
        spSkinGauge1.Value:=spSkinGauge1.Value+1;    ADOSubtemp:= TADOQuery.Create(FrmMain);
        ADOSubtemp.Name :='ADOSubtemp';
        ADOSubtemp.Connection := DataMod.ADOConnection1 ;
        ADOSubtemp.Active :=false;    ADOSubtemp.SQL.Clear;
        //从指定的表中找出文件夹
        ADOSubtemp.SQL.Add('Select * from '+strTableName+
        ' where Directory <>"" order by pid,id');
        // Directory <>"" 表示这是目录名
        try
          ADOSubtemp.Open;
        except
          //可能指定的表不存在所以会出错
          ADOSubtemp.Active :=false;
          ADOSubtemp.Free;
          ADOSubtemp:=nil;
          result:=false;
          exit;
        end;
        if ADOSubtemp.RecordCount >0 then
        begin
          mTreeView.Items.BeginUpdate;
          for i:=0 to ADOSubtemp.RecordCount-1 do
          begin
            if g_bCloseApp then exit;
            spSkinGauge1.Value:=spSkinGauge1.Value+1;
            if spSkinGauge1.Value>=spSkinGauge1.MaxValue then spSkinGauge1.Value:=0;
            Application.ProcessMessages;
            New(MyRecPtr); //分配内存
            LockWindowUpdate(mTreeView.Handle); //锁定刷新
            lid:= ADOSubtemp.FieldByName('id').AsInteger;
            lpid:= ADOSubtemp.FieldByName('pid').AsInteger;
            MyRecPtr^.id := lid;
            MyRecPtr^.pid := lpid;
            MyRecPtr^.strGPName:= strTableName;
            strDirectory:= ADOSubtemp.FieldByName('Name').AsString;
            if lpid =0 then//是第一级目录
            begin
              Nodetemp:=mTreeView.Items.AddChild(Nodep,strDirectory);
              Nodetemp.Data :=  MyRecPtr;
              Nodetemp.ImageIndex :=2;
              Nodetemp.SelectedIndex :=2;
            end
            else
            begin
              //从光盘的起始索引+1开始查找
             try
              for j:=nGpBeginIndex+1 to mTreeView.Items.Count -1 do
              begin
                //找到对应的上级目录
                if (PMyRec(mTreeView.Items[j].Data)^.id =MyRecPtr.Pid )then
                begin
                   Node:= mTreeView.Items[j];
                   break;
                end;
              end;        //end for j
             except
               mTreeView.Items.EndUpdate ;
               if ADOSubtemp<>nil then
               begin
                  ADOSubtemp.Active :=false;
                  ADOSubtemp.Free;
                  ADOSubtemp:=nil;
               end;
               LockWindowUpdate(0);
               Result:= false;
               exit;
             end;
              if Node<>nil then//防止出现找不到的情况
                Nodetemp:=mTreeView.Items.AddChild(Node,strDirectory)
              else Nodetemp:=mTreeView.Items.Add(nil,strDirectory);
              Nodetemp.ImageIndex :=2;
              Nodetemp.SelectedIndex :=2;
              Nodetemp.Data :=  MyRecPtr;
            end;//end else
            LockWindowUpdate(0);  //解除锁定,此时系统会对所有的可视组件进行刷新
            ADOSubtemp.Next;
          end;
          mTreeView.Items.EndUpdate ;    end;
      finally
        LockWindowUpdate(0);
        if ADOSubtemp<>nil then
        begin
          ADOSubtemp.Active :=false;
          ADOSubtemp.Free;
          ADOSubtemp:=nil;
        end;
        spSkinGauge1.Visible :=false;
        Screen.Cursor := crDefault;
        Result:=true;
      end;
    end;
      

  3.   

    我自己也编程调试了,但是没有通过,麻烦各位帮忙看一下:
    type
      pmyrecord = ^TMyRecord;
      TMyRecord = record
      t_class,t_name,t_sex,t_lxtel,t_zipcode,t_address,t_kiss:string;
      t_no,t_age:string;
      end; procedure Tchakan.CreateSubNodes(mynode:TTreeNode);
    var
      myrecordpointer:pmyrecord;
      tmpdataset:tadodataset;
      tmpnode:ttreenode;
      sqlstr:string;
    begin
      tmpdataset:=tadodataset.Create(nil);
      sqlstr:='t_class='''+pmyrecord(mynode.data)^.t_no+'''';
      tmpdataset.Connection:=adoconnection1;
      tmpdataset.commandtext:='select * from t_base where'+'t_class='''+sqlstr+'order by t_no';
      tmpdataset.cursortype:=ctstatic;
      tmpdataset.CursorLocation:=cluseclient;
      tmpdataset.Active:=true;
      tmpdataset.First;------------------------------------
      while not tmpdataset.Eof do
      begin
      tmpnode:=treeview1.items.addchild(mynode,tmpdataset.fieldvalues['t_name']);
      tmpnode.selectedindex:=tmpnode.level+1;
      new(myrecordpointer);
      myrecordpointer.t_class:=tmpdataset.fieldvalues['t_class'];  //父节点,班级
      myrecordpointer.t_no:=tmpdataset.fieldvalues['t_no'];        //子节点,同学
      myrecordpointer.t_age:=tmpdataset.fieldvalues['t_age'];
      myrecordpointer.t_name:=tmpdataset.fieldvalues['t_name'];
      myrecordpointer.t_sex:=tmpdataset.fieldvalues['t_sex'];
      myrecordpointer.t_lxtel:=tmpdataset.fieldvalues['t_lxtel'];
      myrecordpointer.t_address:=tmpdataset.fieldvalues['t_address'];
      myrecordpointer.t_zipcode:=tmpdataset.fieldvalues['t_zipcode'];
      myrecordpointer.t_kiss:=tmpdataset.fieldvalues['t_kiss'];
      //myrecordpointer.t_photo:=tmpdataset.fieldvalues['t_photo'];
      tmpnode.data:=myrecordpointer;
      createsubnodes(tmpnode);
      tmpdataset.next;
      end;
      tmpdataset.active:=false;
      tmpdataset.free;
      end;procedure Tchakan.FormCreate(Sender: TObject);
    var
    myrecordpointer:pmyrecord;
    begin
      new(myrecordpointer);
      myrecordpointer.t_class:='';
      myrecordpointer.t_no:='';
      myrecordpointer.t_age:='';
      myrecordpointer.t_name:=treeview1.items[0].text;
      myrecordpointer.t_sex:='';
      myrecordpointer.t_lxtel:='';
      myrecordpointer.t_address:='';
      myrecordpointer.t_zipcode:='';
      myrecordpointer.t_kiss:='';
      treeview1.items[0].data:=myrecordpointer;
      createsubnodes(treeview1.items[0]);end;
    调试运行时错误提示:“ = 附近有语法错误”,program reset后光标指向后面有横线的那一条语句!!!帮忙解决!
      

  4.   

    yanghai0437(流浪者)的太繁琐了,没必要。个人较同意aiunong(凡)的说法,虽然不太具体,不过查一下aiunong(凡)说的那几个东东,就明白了
      

  5.   

    procedure TForm1.FormShow(Sender: TObject);
    var
      TreeNodeProvince,TreeNodeCity : TTreeNode;
      NodeDataRecPtr : PNodeDataRec;
      RegAdmiCode,Temp : String;
    begin
      TreeView1.Items.Clear;
      //TreeNodeProvince := nil;
      //TreeNodeCity := nil;
      with Query1 do
      begin
        Close;
        SQL.Clear;
        SQL.Text := 'select * from Admipartition order by ADMIPARTITIONNO asc';
        try
          Open;
        except
          Close;
          Exit;
        end;
        //----^    if not (bof and eof) then
        begin
          First;
          while Not eof do
          begin
            Temp := fieldbyname('AdmipartitionNo').AsString;        if Copy(fieldbyname('AdmipartitionNo').AsString,3,4) = '0000' then
            begin
              New(NodeDataRecPtr);
              NodeDataRecPtr^.AdmiName := FieldByName('ADMIPARTITIONNAME').AsString;
              NodeDataRecPtr^.AdmiCode := FieldByName('ADMIPARTITIONNO').AsString;
              TreeNodeProvince := TreeView1.Items.AddObject(nil,FieldByName('ADMIPARTITIONNAME').AsString +
                            '' + FieldByName('ADMIPARTITIONNO').AsString,NodeDataRecPtr);         // TreeNodeProvince := TreeView1.Items.Add(nil,FieldByName('ADMIPARTITIONNAME').AsString
                  //          );
            end
            else
              if Copy(FieldByName('ADMIPARTITIONNO').AsString,5,2) = '00' then
              begin
                New(NodeDataRecPtr);
                NodeDataRecPtr^.AdmiName := FieldByName('ADMIPARTITIONNAME').AsString;
                NodeDataRecPtr^.AdmiCode := FieldByName('ADMIPARTITIONNO').AsString;
                TreeNodeCity := TreeView1.Items.AddChildObject(TreeNodeProvince,FieldByName('ADMIPARTITIONNAME').AsString,NodeDataRecPtr);
              end
              else
              begin
                New(NodeDataRecPtr);
                NodeDataRecPtr^.AdmiName := FieldByName('ADMIPARTITIONNAME').AsString;
                NodeDataRecPtr^.AdmiCode := FieldByName('ADMIPARTITIONNo').AsString;
                TreeView1.Items.AddChildObject(TreeNodeCity,FieldByName('ADMIPARTITIONNAME').AsString,NodeDataRecPtr);          end;
            Next;
          end;
        end;
      end;
      TreeView1.SetFocus;
      TreeView1Click(Self);
    end;