最近在网上看到很多人问TREEVIEW的使用方法,当然,例子代码也非常多,这是我之前写的,将以下代码贴出来,抛砖引玉,仅供参考一下,
本人水平有限,只能实现一些简单的功能...各位牛人别拍砖啊..-_-...
注: 在 FormShow 中的 Filter 只是为了进行权限判断,只加载具备条件的节点,少了一段代码,就是在保存之后插入一个
节点和数组元素...--------------------------------------------------------------------------------------------
表结构: 
dp_companytype                    dp_company        
------------------------------------------------------------------
   Coid   char Companytypeid int
   Companytypeid int parentid int
   AreaID int
   isopen bit
   name char数据:  
dp_companytype   dp_company                    
_________________________________________________  ____________________________________________          
   parentid      |    Companytypeid | Areaname Companytypeid  | coid |  isopen |  name
_________________|__________________|____________ _________________|______|_________|_________
    0  |   1     | 华南区        1          |  001 |   1   | test1
_________________|__________________|____________ _________________|______|_________|_________
    1  |     2     | 广东省                   2  |  002 |   0   | test2
_________________|__________________|____________ _________________|______|_________|_________
    2  |        3     | 深圳市                   3  |  003 |   0   | test3
_________________|__________________|____________       _________________|______|_________|_________
    2  |   4     | 广州市                   5  |  004 |   1   | test4
_________________|__________________|____________ _________________|______|_________|_________
    3  |   5     | 福田区                   4  |  005 |   1   | test5
_________________|__________________|____________ _________________|______|_________|_________
          6  |  006 |   1   | test6
_________________|______|_________|_________
------------------------------------------------------------------------------------------------------------1.树节点添加流程:
  (1) 首先从 dp_companytype  表中加载出所有的地区,形成一个一级节点,AddParentNode过程
   所有区域
      |
     |---华南区
      |     |
     |    |___广东省
      |    |  |
     |     |     |___广州市  
      |     |     | 
     |     |     |
     |     |     | 
     |    |  |___深圳市 
      |    |  |     |
     |     |     |     |---福田区
      |     |     |     |
 
  
  (2) 之后再从 dp_company  表中查询 Companytypeid 与 dp_companytype 表中 Companytypeid 相同的记录,将其添加到相应的区域下
   AddChildNode(ChildNode:TTreeNode;nCompanytypeid:integer;Isparentid:boolean);
  参数说明 : 1.新增子节点的父节点,2.查找的二级节点ID,3.该节点是否无父节点
  
  (3) dp_company 表中有些 Companytypeid 在 dp_companytype 中不存在,当然也要加载到树上,作为单独的一个二级节点添加
   
  (4) 添加最后一级节点,即 dp_company中的节点   SelectCoid(aChildNode,aChildquery.fieldbyname('Companytypeid').AsInteger);  //添加相应的店名
     
  (5) 最后形成的节点应该是:
 
   所有区域
      |
     |---华南区
      |     |
     |     |___test1
     |     |  
     |    |___广东省
      |    |  |
     |    |  |___test2
     |    |  |
     |     |     |___广州市  
      |     |     |     |
     |     |     |     |___test5
     |     |     | 
     |    |  |___深圳市 
      |    |  |     |
     |     |     |     |___test3
     |     |     |     |   
     |     |     |     |---福田区
      |     |     |     |     |
     |     |     |     |     |---test4
     |     |     |     |     |
     |__________________________test6 (由于它的companytypeid 在 dp_companytype中不存在,故将它加到一级子节点上)当然程序有根据 isopen  将相应的节点差色(最后一级子节点),之后就是数据操作,比如修改 dp_company 中 Companytypeid 的值,则将相应的记录移动别的节点上,为了使数据和界面分隔,将代码写在 datasource 的DataChange 事件中    

解决方案 »

  1.   

    这破CSDN.我排了好久才排好,一发又乱了,.靠..啥也不说了,贴代码
    unit CompanyOpenBf;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, BasBrowFrmF, DB, LJDataSource, Menus, ActnList, LJReportEh, SqlExpr,
      AppEvnts, LJSysStyle, LJFormInfo, StdCtrls, ComCtrls, Grids, DBGridEh,
      ExtCtrls, Buttons, LJDBNav,dbclient, DBGrids,UntCommon, Mask, DBCtrls,
      LJDBEditx, ADODB;type
      TCoid=record                  //记录用来存放 coid 编号
        Coid:string;
        Isopen:boolean;
        Companytypeid:integer;
        Areaid:Variant;
        nNodeData:TTreeNode;
      end;
      PTCoid=^TCoid;                //结构体指针
      TCompanyOpenB = class(TBasBrowFrm)
        TreeView1: TTreeView;
        DataSource1: TDataSource;
        procedure FormShow(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
        procedure dsBrow_GroupLJDataChange(Sender: TObject; Field: TField);
        procedure FormActivate(Sender: TObject);
        procedure SBCheckClick(Sender: TObject);
        procedure TreeView1Change(Sender: TObject; Node: TTreeNode);
        procedure cbSearchEnter(Sender: TObject);
        procedure cbSearchChange(Sender: TObject);
        procedure TreeView1CustomDrawItem(Sender: TCustomTreeView;
          Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
        procedure FormInfoAfterApplyUpdates(Sender: TObject);
        procedure DataSource1DataChange(Sender: TObject; Field: TField);
      private
        { Private declarations }
      public
        node:TTreeNode;
        insertedstate:boolean; // 检查自动编号重复
        Insertrecord:boolean; //新增标志
        Hasbillnode:boolean;
        IsFilter:boolean;
        Areaid,Companytypeid,Parentid:integer;
        MyList:TStringList;
        mSql:string;          
        procedure SelectCoid(ChildCoid:TTreeNode;nCompanytypeid:integer);                     //取得餐厅信息
        procedure AddParentNode;                                                              //添加顶级节点
        procedure AddChildNode(ChildNode:TTreeNode;nCompanytypeid:integer;Isparentid:boolean);//添加二级节点
        procedure AddCoidnode(CoidNode:TTreeNode;Coidchild:TSQLquery);                        //添加餐厅节点
        //取消保存
        procedure CancelPost(ColorCancel:boolean;nSelect,oSelect:integer;oIsopen:boolean;oAreaid:integer;oCoid:string);{ Public declarations }
        //返回当前要操作的节点
        function  ReturnSelectIndex(oSelect:integer):integer;
        //保存之后改变数组信息和移动节点
        procedure AfterPost(IsNotExpand,NodeCancel:boolean;Indexitem,nAreaid,nCompanytypeid,oCompanytypeid:integer;nCoid:string);
      end;                    //注意,后面四个过程中所传递参数与 dmdp_res模块中定义的参数名称一致,以便以区分
    var
        CompanyOpenB: TCompanyOpenB;
        Index:longint;        //数组下标     
        pCoid:array [0..10000]   of PTCoid;  //
        Temp:PTCoid;          //移到节点时的中间变量
        mForm:TForm;
        mTForm:TComponentClass;
        procedure SetAreaRight;
    implementationuses DMDP_RESf, DMDP_SYSf, CompanyOpenEf, commLib, DMDP_BASf,DMdp_midf,BasCompanyTypeBF,LoginDPf,
      ResearchHouseEf, ResearchWorkEf, ResearchPasserEf, BusType,BasEditSF,BasEditFrmF;{$R *.dfm}procedure TCompanyOpenB.FormShow(Sender: TObject);
     var s:string;
         i:integer;
    begin
      inherited;
      //lj 2003-07-25 add
      //增下句的目的:  由于为了提升速度,浏览窗口与编辑窗口使用了不同的数据集,
      // 使得权限控制只控制到了浏览数据集,为此,增加以下语句
      //  设置编辑窗口数据集的权限
      forminfo.dsmain:=dmdp_res.dsDP_Company;
      SetRight(RightText);
      forminfo.dsmain:=dsbrow;
      //------------------------
      if assigned(TForm(CompanyOpenE)) then     //把窗体 放在panel上
      begin
        mForm:=nil;
      end;
      application.CreateForm(TCompanyOpenE,TForm(CompanyOpenE));
      CompanyOpenE.Align:=alClient;
      CompanyOpenE.WindowState:=wsMaximized;
      CompanyOpenE.Position:=poDesigned;
      TForm(CompanyOpenE).Dock(Panel1,Panel1.ClientRect);
      TForm(CompanyOpenE).Show;
      CompanyOpenE.Color:=clBtnFace; // CompanyOpenE.LJApplyUpdates.Top:=327;
      //-----------------------
      Index:=0;
      DMDP_SYS.cdsOperator.Filter:=' operid='''+OperID+'''';
      if dmdp_sys.cdsOperator.FieldByName('dp_allarearight').AsBoolean then   //为真,无需作权限判断
      begin
        dmdp_sys.cdsOperator.Filtered:=false;
      end
      else
      begin
        IsFilter:=true;
        Mylist:=TStringList.create;
        Mylist.clear;
        dmdp_sys.cdsOperator.Filtered:=true;
        Areaid:=dmdp_sys.cdsOperator.fieldbyname('DP_Areaid').AsInteger;
        dmdp_sys.cdsCommon.Close;                             //查询 companytypeid
        dmdp_sys.cdsCommon.CommandText:='select DIStinct companytypeid from dp_company where areaid='''+inttostr(Areaid)+'''';
        dmdp_sys.cdsCommon.Open;
        Mylist.Add(' ( ');
        For i:=0 to dmdp_sys.cdscommon.recordcount-1 do
        begin
          Companytypeid:=dmdp_sys.cdscommon.fieldbyname('Companytypeid').asinteger;
          dmdp_bas.cdsDP_CompanyType.Filter:=' Companytypeid='''+inttostr(Companytypeid)+'''';
          dmdp_bas.cdsDP_CompanyType.Filtered:=true;
          Parentid:=dmdp_bas.cdsdp_companytype.fieldbyname('parentid').asinteger;
          Mylist.add(' (Parentid='''+inttostr(Companytypeid)+''' or companytypeid='''+inttostr(Parentid)+''') or Companytypeid='''+inttostr(Companytypeid)+''' ');
          if (Mylist.text<>'') and (i<>dmdp_sys.cdscommon.recordcount-1) then
            Mylist.add(' or ');
          if s<>'' then
            s:=s+' or';
          s:=s+' Companytypeid='''+inttostr(Companytypeid)+''' or companytypeid='''+inttostr(Parentid)+'''';
          dmdp_bas.cdsDP_CompanyType.Filtered:=false;
          dmdp_sys.cdscommon.next;
        end;
        Mylist.Add(' ) ');
        s:=' and ('+s+')';
        Mylist.Add(s);
        Companytypeid:=dmdp_sys.cdsCommon.fieldbyname('Companytypeid').AsInteger;
        Parentid:=dmdp_bas.cdsDP_CompanyType.fieldbyname('parentid').AsInteger;
        dmdp_bas.cdsDP_CompanyType.Filtered:=false;
      end;
      treeview1.SetFocus;
      node:=treeview1.Selected;
      TreeView1.Items.BeginUpdate;
      AddParentNode;
      TreeView1.Items.EndUpdate;
      dmdp_sys.cdsOperator.Filter:='';
      if  dmdp_sys.cdsOperator.Filtered then
        dmdp_sys.cdsOperator.Filtered:=false;
      if dmdp_bas.cdsDP_CompanyType.Filtered then
        dmdp_bas.cdsDP_CompanyType.Filtered:=false;
    end;
      

  2.   


    procedure TCompanyOpenB.AddParentNode;                         //添加父节点
      var aParentNode:TTreeNode;
          aParentquery:TSQLquery;
          idx:integer;
          mFirst:boolean;
    begin
      mFirst:=true;
      aParentquery:=TSQLquery.Create(nil);
      aParentquery.SQLConnection:=DMdp_mid.SQLConnection1;
      with dmdp_sys.cdsCommon do
      begin
        if IsFilter then               //过滤完再次查询
        begin
          for idx:=0 to Mylist.Count-1 do
          begin
            mSql:=mSql+Mylist.Strings[idx];
          end;      Close;
          CommandText:= ' select  *  from dp_companytype where (parentid not in(select companytypeid from dp_companytype)'+
                        ' or parentid='''' or parentid is null or parentid=0 ) and '+mSql+'  order by CompanyTypeID ';
          open;
        end
        else
        begin
          Close;
          CommandText:=' select  *  from dp_companytype where parentid not in(select companytypeid from dp_companytype) or parentid='''''+
                       ' or parentid is null or parentid=0  order by CompanyTypeID';
          Open;
        end;
        for idx:=0  to RecordCount-1 do
        begin
          if (Index<>0) or (mFirst=false) then
             Inc(Index);
          New(pCoid[Index]);
          aParentNode:=treeview1.Items.AddChild(node,dmdp_sys.cdsCommon.fieldbyname('name').AsString);
          pCoid[Index].Coid:='';     // 没有COID,则存空值
          pCoid[Index].Companytypeid:=dmdp_sys.cdsCommon.fieldbyname('Companytypeid').AsInteger;
          pCoid[Index].nNodeData:=aParentNode;
          pCoid[Index].Areaid:=null;
          pCoid[Index].Isopen:=true;
          aParentNode.Data:=pCoid[Index];
          AddChildNode(aParentNode,dmdp_sys.cdsCommon.fieldbyname('Companytypeid').AsInteger,true);  //最后一个参数为添加顶节点标志
          Next;
          mFirst:=false;
        end;
      end;
      if IsFilter then                                 //添加所属区域内的餐厅
        mSql:=' select addrco,isopen,coid,companytypeid ,Areaid from dp_company where  (companytypeid is null '+
              ' or companytypeid=0 or companytypeid='''') and Areaid='''+inttostr(Areaid)+''' order by companytypeid'
      else
        mSql:=' select addrco,isopen,coid,companytypeid ,Areaid from dp_company where  companytypeid is null '+
              ' or companytypeid=0 or companytypeid='''' order by companytypeid';
      aParentquery.Close;                            //添加没有设 companytypeid 的餐厅节点
      aParentquery.SQL.Clear;
      aParentquery.SQL.Text:=mSql;
      aParentquery.Open;
      AddCoidnode(node,aParentquery);
      aParentquery.Free;
    end;procedure TCompanyOpenB.SelectCoid(ChildCoid: TTreeNode;nCompanytypeid:integer);  //添加餐厅节点
     var idx:integer;
         AddrNode:TTreeNode;
         Coidquery:TSQLquery;
         str:string;
    begin
      Coidquery:=TSQLquery.Create(nil);
      Coidquery.SQLConnection:=DMdp_mid.SQLConnection1;
      with Coidquery do
      begin
        if IsFilter then
          str:=' select addrco,isopen,coid,companytypeid ,Areaid '+
                     ' from dp_company where companytypeid= '+
                     ' '''+inttostr(nCompanytypeid)+''' and areaid='''+inttostr(Areaid)+''' order by coid'
        else
          str:=' select addrco,isopen,coid,companytypeid ,Areaid '+
                     ' from dp_company where companytypeid= '+
                     ' '''+inttostr(nCompanytypeid)+''' order by coid';
        Close;
        Sql.Text:=str;
        open;
        AddCoidnode(ChildCoid,Coidquery);    //添加餐厅节点
      end;
      Coidquery.Free;
    end;                                     //添加餐厅节点
    procedure TCompanyOpenB.AddCoidnode(CoidNode:TTreeNode;Coidchild:TSQLquery);
     var idx:integer;
         AddrNode:TTreeNode;
    begin
      For idx:=0 to Coidchild.RecordCount-1 do
      begin
        Inc(Index);
        New(pCoid[Index]);
        AddrNode:=treeview1.Items.AddChild(CoidNode,Coidchild.fieldbyname('addrco').AsString);
        pCoid[Index].Coid:=Coidchild.fieldbyname('coid').AsString;
        pCoid[Index].Areaid:=Coidchild.fieldbyname('Areaid').AsInteger;
        pCoid[Index].nNodeData:=AddrNode;
        pCoid[Index].Companytypeid:=Coidchild.fieldbyname('Companytypeid').AsInteger;
        if Coidchild.FieldByName('Isopen').AsBoolean then
          pCoid[Index].Isopen:=true
        else
          pCoid[Index].Isopen:=false;
        AddrNode.Data:=pCoid[Index];
        Coidchild.next;
      end;
    end;
    procedure TCompanyOpenB.AddChildNode(ChildNode: TTreeNode;nCompanytypeid:Integer;Isparentid:boolean); //添加二级子节点
      var aChildNode:TTreeNode;
          aChildquery,aquery:TSQLquery;
          idx:integer;
          Hasadd:boolean;
          str,mstr:string;
    begin
       aquery:=TSQLquery.Create(nil);
       aquery.SQLConnection:=DMdp_mid.SQLConnection1;
       aChildquery:=TSQLquery.Create(nil);
       aChildquery.SQLConnection:=DMdp_mid.SQLConnection1;
       with aChildquery do
       begin
         if IsFilter then
         begin
           str:=' select * from dp_companytype where '+mSql+' and parentid='''+inttostr(nCompanytypeid)+''' order by companytypeid';
           mstr:='select companytypeid from dp_company where companytypeid='''+inttostr(nCompanytypeid)+'''  and Areaid='''+inttostr(Areaid)+''' order by companytypeid';
         end
         else
         begin
           str:=' select * from dp_companytype where ParentID='''+inttostr(nCompanytypeid)+''' order by CompanyTypeID';
           mstr:=' select companytypeid from dp_company where companytypeid='''+inttostr(nCompanytypeid)+''' order by companytypeid';
         end;
         close;
         SQL.Clear;
         SQL.Text:= str;
         open;
         aquery.Close;
         aquery.SQL.Text:=mstr;
         aquery.Open;
         if (aquery.RecordCount<>0) and Isparentid then  //存在餐厅节点时和子节点时,先添加餐厅节点
         begin
           SelectCoid(ChildNode,nCompanytypeid);         //加判断,防止重复添加两次(该节点只存在餐厅节点时)
           Hasadd:=true;
         end;
         if (RecordCount=0) and Isparentid and (Hasadd=false) then //没有二级节点只有餐厅节点时,直接添加餐厅资料
         begin                                                     //区分是否为顶级节点
           SelectCoid(ChildNode,nCompanytypeid);
         end
         else
         begin
           Hasbillnode:=true;
           for idx:=0  to RecordCount-1 do
           begin
             Inc(Index);
             New(pCoid[Index]);
             aChildNode:=treeview1.Items.AddChild(ChildNode,aChildquery.fieldbyname('name').asstring);
             pCoid[Index].Coid:='';            //没有COID,存空值
             pCoid[Index].Areaid:=null;
             pCoid[Index].Isopen:=true;
             pCoid[Index].nNodeData:=aChildNode;
             pCoid[Index].Companytypeid:=aChildquery.fieldbyname('Companytypeid').AsInteger;
             aChildNode.Data:=pCoid[Index];
             AddChildNode(aChildNode,aChildquery.fieldbyname('Companytypeid').AsInteger,false);
             SelectCoid(aChildNode,aChildquery.fieldbyname('Companytypeid').AsInteger); //添加相应的店名
             next;
           end;
         end;
       end;
       aChildquery.Free;
       aquery.Free;
    end;
      

  3.   

    procedure TCompanyOpenB.TreeView1Change(Sender: TObject; Node: TTreeNode);
      var ParentNode,fCompanytypeid:string;
          IsCheck:boolean;
          Selectid:integer;
    begin
      inherited; //新增之后将按钮状态设置为FALSE,所以要将按钮设置回原来的状态
      Selectid:=treeview1.Selected.AbsoluteIndex-1;
      if Selectid=-1 then
        exit;
      if Insertrecord then
      begin
        CompanyOpenE.RefreshEnabled;
        Insertrecord:=false;
      end;
      if (assigned(CompanyopenE)) and(CompanyOpenE.LJApplyUpdates.Enabled)  then
      begin
        IsCheck:=dmdp_res.cdsdp_company.FieldByName('CheckFlag').AsBoolean;
        if (IsCheck=false) and (Messagedlg('保存已修改的内容吗?',mtConfirmation,[mbYes,mbNo],0)=mryes) then
        begin
          dmdp_res.NodeCancel:=false;       //保存
          CompanyOpenE.LJApplyUpdatesClick(Sender);
        end
        else
        begin
          if IsCheck then
            showmessage('已审核的数据不能修改');
          dmdp_res.cdsDP_Company.CancelUpdates;
          CompanyOpenE.RefreshEnabled;
        end;
      end;
      if forminfo.DsBrow.DataSet<>dmdp_res.cdsDP_Company_open_b then  //新增后,数据集为 cdsDP_Company
        forminfo.DsBrow.DataSet:=dmdp_res.cdsDP_Company_open_b;
      if DMDP_RES.cdsDP_Company_open_b.Filtered then                  //执行查找后,要将数据集过滤状态设为假
        DMDP_RES.cdsDP_Company_open_b.filtered:=false;
      if treeview1.Selected.Text='餐厅资料' then
        exit;
      with  DMDP_RES.cdsDP_Company_open_b do
      begin
        Close;
        CommandText:=
    //注意,此处不用 selectid 是因为防止用户在修改数据后取消保存时(节点着色),其它地方选中了要操作的节点
           'select *  FROM DP_COMPANY  where coid=:coid';             //故不能用用户当前选中的节点
        Params.ParamByName('coid').Value:=pCoid[treeview1.Selected.AbsoluteIndex-1].Coid;
        Open;
        mIsOpen:=dmdp_res.cdsDP_Company_open_b.FieldByName('isopen').AsBoolean;
      end;
      forminfo.DsMain.DataSet:=dmdp_res.cdsDP_Company;
      if forminfo.DsMain.DataSet.Filtered then
        forminfo.DsMain.DataSet.Filtered:=false;
      forminfo.SqlWhere:=' COID='''+trim(DMDP_RES.cdsDP_Company_open_b.fieldbyname('coId').asstring)+'''';
      Query;
      if pCoid[treeview1.Selected.AbsoluteIndex-1].isopen then
        dmdp_res.cdsDP_Company.tag:=1
      else
        dmdp_res.cdsDP_Company.tag:=2;
    end;procedure TCompanyOpenB.cbSearchEnter(Sender: TObject);
     var s:string;
    begin
      inherited;
      if combobox1.ItemIndex=0 then
        s:='select * from dp_company where isopen=1'
      else if combobox1.ItemIndex=1 then
        s:='select * from dp_company where isopen=0';
      dmdp_res.cdsDP_Company_open_b.Close;
      dmdp_res.cdsDP_Company_open_b.CommandText:=s;
      dmdp_res.cdsDP_Company_open_b.Open;
    end;procedure TCompanyOpenB.cbSearchChange(Sender: TObject);
     var s:string;
    begin
      if forminfo.DsBrow.DataSet<>dmdp_res.cdsDP_Company_open_b then  //新增后,数据集为 cdsDP_Company
        forminfo.DsBrow.DataSet:=dmdp_res.cdsDP_Company_open_b;
      inherited;
      forminfo.DsMain.DataSet:=dmdp_res.cdsDP_Company;
      if combobox1.ItemIndex=0 then //已开业餐厅
      begin
        mIsOpen:=true;
        s:=' and  isopen=1 ';
      end
      else
      begin
        mIsOpen:=false;
        s:=' and isopen=0 ';
      end;
      if IsFilter then
        s:=s+' and Areaid='''+inttostr(Areaid)+'''';//不允许查询所属区域之外的资料
      forminfo.SqlWhere:=' Coid='''+dmdp_res.cdsDP_Company_open_b.fieldbyname('Coid').AsString+''''+s;
      query;
    end;procedure TCompanyOpenB.TreeView1CustomDrawItem(Sender: TCustomTreeView;
      Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
    begin
      if Node.Level=0 then
         exit;
      if PTCoid(Node.Data).Isopen=false then   //强制转换
        TreeView1.Canvas.Font.Color:=clred;
    end;procedure TCompanyOpenB.FormInfoAfterApplyUpdates(Sender: TObject);
     var i,j:integer;
    begin
      i:=TreeView1.Selected.AbsoluteIndex-1;
      For j:=i to Index do       //删除数组元素
      begin
        pCoid[j]:=pCoid[j+1];
      end;
      TreeView1.Selected.Delete;                                 
    end;
    procedure TCompanyOpenB.CancelPost(ColorCancel:boolean;nSelect,oSelect:integer;oIsopen:boolean;oAreaid:integer;oCoid:string);
      var i:integer;
    begin
      if pCoid[nSelect].Isopen<>oIsopen  then
      begin
        ColorCancel:=true;
        TreeView1.OnChange:=nil;    //取消保存时选中原来操作的节点再着色
        TreeView1.Items[oSelect].Selected:=true;
        DataSource1DataChange(Datasource1,dmdp_res.cdsDP_CompanyIsOpen);
      end;
      if pCoid[nSelect].Areaid<>oAreaid then //放弃保存修改的AREAID,将数组的值修改为原来的
      begin
        i:=nSelect;
        TreeView1.OnChange:=nil;
        TreeView1.Items[i+1].Selected:=true;
        pCoid[i].Areaid:=oAreaid;
        pCoid[i].Coid:=oCoid;
        TreeView1.OnChange:=TreeView1Change;
      end;
    end;procedure TCompanyOpenB.DataSource1DataChange(Sender: TObject;
      Field: TField);
     var isopen,nIsopen:boolean;
         i:integer;
    begin
      if field=nil then
        exit;
      if assigned(CompanyopenB) and (Insertrecord=false)  then
      begin
        if uppercase(Field.FieldName)='ISOPEN' then
        begin
          dmdp_res.IsNotExpand:=false;
          i:=dmdp_res.oSelectIndex;
          nIsopen:=dmdp_res.cdsdp_company.FieldByName('isopen').AsBoolean;
          isopen:=pCoid[i].Isopen;
          if isopen=nIsopen then
            exit;
          pCoid[i].Isopen:=nIsopen;
          if pCoid[i].Isopen=false then
            TreeView1.Canvas.Font.Color:=clred
          else
            TreeView1.Canvas.Font.Color:=clBlack;
          if dmdp_res.ColorCancel then
          begin
             TreeView1.Items[dmdp_res.oSelectIndex+1].Selected:=true;
             dmdp_res.ColorCancel:=false;
          end
          else
          begin
             TreeView1.OnChange:=nil;
             TreeView1.Items[i+1].Selected:=true;
          end;
          if (dmdp_res.ColorCancel=false) or (dmdp_res.IsNotExpand=false) then
            TreeView1.OnChange:=TreeView1Change;
          TreeView1.SetFocus;
        end;
        if uppercase(Field.FieldName)='COID'   then
        begin
          i:=ReturnSelectIndex(dmdp_res.oSelectIndex);
          dmdp_res.nAreaid:=dmdp_res.cdsDP_Company.FieldByName('areaid').AsInteger;
          dmdp_res.nCoid:=dmdp_res.cdsdp_company.FieldByName('coid').AsString;
          if dmdp_res.oAreaid<>dmdp_res.nAreaid then  
            pCoid[i].Areaid:=dmdp_res.nAreaid;
          if dmdp_res.oCoid<>dmdp_res.nCoid then
            pCoid[i].Coid:=dmdp_res.nCoid;
        end;
        if uppercase(Field.FieldName)='ADDRCO' then
          TreeView1.Selected.Text:=dmdp_res.cdsDP_Company.fieldbyname('addrco').AsString;
      end;
    end;function TCompanyOpenB.ReturnSelectIndex(oSelect:integer): integer;
      var SelectIndex:integer;
          Default:boolean;
    begin
      if  TreeView1.Selected.AbsoluteIndex=0 then
      begin
        SelectIndex:=oSelect;
        TreeView1.OnChange:=nil;
        Default:=true;
        dmdp_res.IsNotExpand:=true;
        TreeView1.Items[SelectIndex+1].Selected:=true;  //要屏蔽树节点改变事件,注意树的绝对顺序和数组相差1,故要加上1
      end                     
      else
      begin
        SelectIndex:=TreeView1.Selected.AbsoluteIndex-1;
      end;
        Result:=SelectIndex;
      if Default then
      begin
        Treeview1.OnChange:=TreeView1Change;
        Default:=false;
      end;  
    end;end;
      

  4.   


    procedure TCompanyOpenB.AfterPost(IsNotExpand, NodeCancel: boolean;
       Indexitem,nAreaid, nCompanytypeid,oCompanytypeid: integer; nCoid: string);
      var i,j,k:integer;                                                  
    begin
      i:=0;j:=0;k:=0;
      IsNotExpand:=false;    //同时打开餐厅资料输入指引和该窗体时, dmdp_res.cdsdp_company 不能保存
      k:=ReturnSelectIndex(dmdp_res.oSelectIndex); //在餐厅资料输入指引中,修改了餐厅资料时,要将树定位到该笔记录
    if  oCompanytypeid<> nCompanytypeid then
      begin
        if NodeCancel=false then //保存,该值在编辑之前设为真,若是取消保存,则不执行该过程
        begin                         //修改餐厅类别而直接选中其它节点的情况下需要选回原来的节点
          k:=Indexitem;               //原来的编号
          TreeView1.OnChange:=nil;
          IsNotExpand:=true;
          TreeView1.Items[k+1].Selected:=true;
          NodeCancel:=true;
        end;
        For i:=0 to Index do
        begin
          if pCoid[i].Companytypeid=nCompanytypeid then
          begin
            pCoid[k].Companytypeid:=nCompanytypeid;
            Temp:=pCoid[k];
            TreeView1.Selected.MoveTo(pCoid[i].nNodeData,naAddChildFirst);
            if k<i then          //往后移
            begin
              for j:=k to i do
              begin
                pCoid[j]:=pCoid[j+1];
              end;
              pCoid[i]:=Temp;
            end;
            if k>i then          //往前移
            begin
              for j:=k-1 downto  i do
              begin
                pCoid[j+1]:=pCoid[j];
              end;
              pCoid[i+1]:=Temp;
            end;
            break;
          end;
        end;
      end;
      if IsNotExpand  then
        TreeView1.OnChange:=TreeView1Change;
      

  5.   

    楼主辛苦了!CSDN的排版确实很烦人,我还发帖问过呢!
    这贴子先放一下,下午有空时仔细研读!