DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: a1871584487
今日帖子: 9
在线用户: 7
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 yangzh (喜羊羊) ★☆☆☆☆ -
盒子活跃会员
2004/3/11 12:13:40
标题:
用两个表创建TreeView树的问题? 浏览:1974
加入我的收藏
楼主: 用两个表创建TreeView树的问题?

如图:以表2为要根结点,表1为表2的子结点。
请高手指教如何编写。
此帖子包含附件:
JPEG 图像
大小:57.7K
----------------------------------------------
DELPHI家园QQ群:186629229
作者:
男 yangzh (喜羊羊) ★☆☆☆☆ -
盒子活跃会员
2004/3/11 14:05:55
1楼: 这是我编的一个小程序还不完善你可以看看
procedure TForm1.FormCreate(Sender: TObject);
var
  TreeNode,TreeChildNode,StudentNode : TTreeNode;
  CID : Integer;
begin
  ADOTableClass_Info.Close;
  ADOTableClass_Info.Open;
  ADOTableClass_Info.First;
  TreeView1.Items.BeginUpdate;
  TreeNode := TreeView1.Items.Add(nil,'班级');
  while not ADOTableClass_Info.Eof do
  begin
    TreeChildNode := TreeView1.Items.AddChild(TreeNode,
      ADOTableClass_Info.FieldByName('Class_Name').AsString);
    TreeChildNode.Data := PChar(ADOTableClass_Info.FieldByName('Class_ID').AsInteger);
    CID := ADOTableClass_Info.FieldByName('Class_ID').AsInteger;
    if ADOQueryStudent_Info.State in [dsOpening] then
    ADOQueryStudent_Info.Close;
    ADOQueryStudent_Info.SQL.Clear;
    ADOQueryStudent_Info.SQL.Add('Select * From Student_Info');
    ADOQueryStudent_Info.SQL.Add('Where Class_ID='+IntToStr(CID));
    ADOQueryStudent_Info.Open;
    while not ADOQueryStudent_Info.Eof do
    begin
      StudentNode:=TreeView1.Items.AddChild(TreeChildNode,
        ADOQueryStudent_Info.FieldByName('Name').AsString);
      StudentNode.Data := PChar(ADOQueryStudent_Info.FieldByName('Student_ID').AsInteger);
      ADOQueryStudent_Info.Next;
    end;
    ADOTableClass_Info.Next;
  end;
  TreeView1.Items.EndUpdate;
  ADOQueryStudent_Info.Close;
  ADOQueryStudent_Info.SQL.Clear;
  ADOQueryStudent_Info.SQL.Add('Select * From Student_Info');
  ADOQueryStudent_Info.SQL.Add('Where Student_ID = :Student_ID');
end;



procedure TForm1.TreeView1Change(Sender: TObject; Node: TTreeNode);
var
  //Str : String;
  SID : integer;
begin
  EditedNode := Node;
  if (Node.Level <> 0) then
  begin
  SID := Integer(Node.Data);
  //Str := IntToStr(SID);
  //ShowMessage(Str);
  ADOQueryStudent_Info.Close;
  ADOQueryStudent_Info.Parameters.ParamByName('Student_ID').value := SID;
  ADOQueryStudent_Info.Open;

  end;
----------------------------------------------
DELPHI家园QQ群:186629229
作者:
男 wgyjacky (wgyjacky) ★☆☆☆☆ -
盒子活跃会员
2004/3/11 15:11:26
2楼: 除用两个循环,还有没有其他更好的办法呢?因为如果数据量大,多表关联的时候就会慢,递归也不是一个很好的办法,请高手指教!
----------------------------------------------
-我喜欢DELPHI,但我不会用.
作者:
男 pdsmgc (pdsmgc) ★☆☆☆☆ -
普通会员
2004/3/12 11:33:46
3楼: 高手来了!!!
看来您对TreeView的基本用法还是比较清楚,但使用的方法不恰当。您可以采用将两表按“UserInfo”进行合成,可在库中建立一视图表即可解决两表之间的联系。最后再按一定条件排序,编程生成TreeView。
----------------------------------------------
-
作者:
男 yangzh (喜羊羊) ★☆☆☆☆ -
盒子活跃会员
2004/3/12 14:07:26
4楼: 还是不行,请高手,帮助我写一个例子好吗?
----------------------------------------------
DELPHI家园QQ群:186629229
作者:
男 pcy13586118106 (pcy2001) ★☆☆☆☆ -
盒子活跃会员
2004/3/14 15:48:59
5楼: 我对这个问题很感兴趣,我也遇到这样的问题,请高手们伸出援助之手?
----------------------------------------------
-将编程进行到底
作者:
男 pdsmgc (pdsmgc) ★☆☆☆☆ -
普通会员
2004/3/15 9:08:11
6楼: 请大家耐心等待,我正在制作。
----------------------------------------------
-
作者:
男 xjr888 (arming) ★☆☆☆☆ -
盒子活跃会员
2004/3/15 9:20:10
7楼: 我认为所有的内容不宜一次读入,这样如果数据量大的话显示会很慢。
可以考虑在节点第一次展开时将子节点内容读入,以后就不需要再次读入了。
在节点变化时,节点操作和数据库操作分开进行,这样也加快了显示。
----------------------------------------------
-
作者:
男 xjr888 (arming) ★☆☆☆☆ -
盒子活跃会员
2004/3/15 9:26:50
8楼: procedure Tfrm_UserManage.TreeViewShowChild(ANode: TTreeNode);
var AChildList: TList;
    AChildInfo: TdpNodeInfo;
    AChildNode, TmpNode: TTreeNode;
    i: integer;
begin
//
  AChildList := TList.Create;
    ANode.DeleteChildren;
  if Db_FindChildList(ANode.Handle, TDpNodeInfo(ANode.Data), AChildList) then
  begin
    for i := 0 to AChildList.Count - 1 do
    begin
      AChildInfo := TDpNodeInfo(AChildList.Items[i]);
      AChildNode := TreeView1.Items.AddChild(ANode, AChildInfo.Name);
      if Db_DpNodeHasChild( AChildInfo ) then
      begin
        // add a tmp node in order to expand
        TmpNode := TreeView1.Items.AddChild(AChildNode, ');  
        TmpNode.Data := nil;
      end;
      AChildNode.ImageIndex    := AChildInfo.ImageIndex;
      AChildNode.SelectedIndex := AChildInfo.SelectedIndex;
      AChildNode.Data          := AChildInfo;
    end;
  end;
  AChildList.Free;
end;

procedure Tfrm_UserManage.TreeView1Expanding(Sender: TObject;
  Node: TTreeNode; var AllowExpansion: Boolean);
begin
    // if has child then expand
    if Node.Item[0].Data = nil then
       TreeViewShowChild(Node);
    ListViewShowUserList(Node);
end;

注:
其中 Db_FindChildList,Db_DpNodeHasChild 为数据库操作, TDpNodeInfo 为自定义的节点内容数据类型
根节点可以手工创建。
----------------------------------------------
-
作者:
男 xiaojun5460 (西门吹灯) ★☆☆☆☆ -
盒子活跃会员
2004/3/15 9:37:06
9楼: 正在学习
----------------------------------------------
-相互学习,共同进步!
作者:
男 wgyjacky (wgyjacky) ★☆☆☆☆ -
盒子活跃会员
2004/3/20 10:17:35
10楼: 同意7楼的做法
----------------------------------------------
-我喜欢DELPHI,但我不会用.
作者:
男 c_hk (c_hk) ★☆☆☆☆ -
盒子活跃会员
2004/3/20 10:50:02
11楼: 举例:
  
const
  //树节点所关联的数据类型
  CNm_TreeNodeStyle_Root = 0;      //树的根节点
  CNm_TreeNodeStyle_ZClass = 1;    //药品大类
  CNm_TreeNodeStyle_MXClass = 2;   //药品细类
  CNm_TreeNodeStyle_Medicine = 3;  //药品

  CNm_TreeNode_ImageIndex_Root = 0;
  CNm_TreeNode_ImageIndex_ZClass = 1;
  CNm_TreeNode_ImageIndex_MXClass = 2;
  CNm_TreeNode_ImageIndex_Medicine = 3;

type
  //节点所关联的数据结构
  PTreeNodeLinkData = ^TTreeNodeLinkData;
  TTreeNodeLinkData = record
    Style        : Integer;      //节点所关联数据的类型
    ItemID       : String;       //号类节点所关联数据的号类编码
    MediAB       : String;       //药品助记码  
    Loaded       : Boolean;      //是否已取得数据
  end;


//--------------------------------------------------------------------------------
procedure TFrmBaseData_Medicine.CreateTreeNode_ZClass(NodeItems: TTreeNodes;
                                  FatherNode: TTreeNode);
var
  CurNode : TTreeNode;
  P : PTreeNodeLinkData;
begin
  NodeItems.BeginUpdate;
  with AdoqryZB do begin
    Close;
    SQL.Clear;
    Parameters.Clear;
    SQL.Add(' Select MediCName, MediCID From MediClass_Base ');
    SQL.Add(' Where Len(MediCID) = 2 ');
    SQL.Add(' Order By MediCName  ');
    Open;
    if RecordCount > 0 then begin
      First;
      while not(Eof) do begin
        CurNode := NodeItems.AddChild(FatherNode, FieldByName('MediCName').AsString);
        CurNode.ImageIndex := CNm_TreeNode_ImageIndex_ZClass;
        CurNode.SelectedIndex := CNm_TreeNode_ImageIndex_ZClass;
        CurNode.StateIndex := CNm_TreeNode_ImageIndex_ZClass;
        New(P);
        P^.ItemID := FieldByName('MediCID').AsString;
        P^.Style := CNm_TreeNodeStyle_ZClass;
        P^.Loaded := True;
        CurNode.Data := P;
        CreateTreeNode_MXClass(NodeItems, CurNode, P^.ItemID);
        if not(Eof) then  Next;
      end; //end while
    end; //end if
    Close;
  end; //end with
  NodeItems.EndUpdate;
end;

//--------------------------------------------------------------------------------
procedure TFrmBaseData_Medicine.CreateTreeNode_MXClass(NodeItems: TTreeNodes;
                                     FatherNode: TTreeNode; sZID: String);
var
  CurNode : TTreeNode;
  P1, P2 : PTreeNodeLinkData;
begin
  with AdoqryMX do begin
    Close;
    SQL.Clear;
    Parameters.Clear;
    SQL.Add(' Select MediCName, MediCID From MediClass_Base ');
    SQL.Add(' Where (Len(MediCID) > 2) ');
    SQL.Add(' And (SubString(MediCID, 1, 2) = :ZID)  ');
    SQL.Add(' Order By MediCID  ');
    Parameters.ParamByName('ZID').Value := sZID;
    Open;
    if RecordCount > 0 then begin
      First;
      while not(Eof) do begin
        CurNode := NodeItems.AddChild(FatherNode, FieldByName('MediCName').AsString);
        CurNode.ImageIndex := CNm_TreeNode_ImageIndex_MXClass;
        CurNode.SelectedIndex := CNm_TreeNode_ImageIndex_MXClass;
        CurNode.StateIndex := CNm_TreeNode_ImageIndex_MXClass;
        New(P1);
        P1^.ItemID := FieldByName('MediCID').AsString;
        P1^.Style := CNm_TreeNodeStyle_MXClass;
        P1^.Loaded := False;
        CurNode.Data := P1;
        //
        CurNode := NodeItems.AddChild(CurNode, ');
        CurNode.ImageIndex := CNm_TreeNode_ImageIndex_Medicine;
        CurNode.SelectedIndex := CNm_TreeNode_ImageIndex_Medicine;
        CurNode.StateIndex := CNm_TreeNode_ImageIndex_Medicine;
        New(P2);
        P2^.ItemID := ';
        P2^.Style := CNm_TreeNodeStyle_Medicine;
        P2^.Loaded := True;
        CurNode.Data := P2;
        if not(Eof) then  Next;
      end; //end while
    end; //end if
    Close;
  end; //end with
end;

//--------------------------------------------------------------------------------
procedure TFrmBaseData_Medicine.CreateTreeNode_Medicine(NodeItems: TTreeNodes;
                                   FatherNode: TTreeNode);
var
  P, PT : PTreeNodeLinkData;
  cNode, CurNode : TTreeNode;
begin
  P := FatherNode.Data;
  if P = nil then  Exit;
  if P^.Style <> CNm_TreeNodeStyle_MXClass then Exit;
  if P^.Loaded then Exit;
  P^.Loaded := True;
  cNode := FatherNode.getFirstChild;
  if cNode <> nil then  NodeItems.Delete(cNode);
  with AdoqryMX do begin
    Close;
    SQL.Clear;
    Parameters.Clear;
    SQL.Add(' Select MediName, MediID, MediAB From MedicineInfo_Base ');
    SQL.Add(' Where MediCID = :CID ');
    SQL.Add(' Order By MediName  ');
    Parameters.ParamByName('CID').Value := P^.ItemID;
    Open;
    if RecordCount > 0 then begin
      First;
      while not(Eof) do begin
        CurNode := NodeItems.AddChild(FatherNode, FieldByName('MediName').AsString);
        CurNode.ImageIndex := CNm_TreeNode_ImageIndex_Medicine;
        CurNode.SelectedIndex := CNm_TreeNode_ImageIndex_Medicine;
        CurNode.StateIndex := CNm_TreeNode_ImageIndex_Medicine;
        New(PT);
        PT^.ItemID := FieldByName('MediID').AsString;
        PT^.MediAB := FieldByName('MediAB').AsString;
        PT^.Style := CNm_TreeNodeStyle_Medicine;
        PT^.Loaded := True;
        CurNode.Data := PT;
        if not(Eof) then  Next;
      end; //end while
    end; //end if
    Close;
  end; //end with
end;


//--------------------------------------------------------------------------------
procedure TFrmBaseData_Medicine.FreeNodeData(Node: TTreeNode);
var
  P : PTreeNodeLinkData;
  ChildNode : TTreeNode;
begin
  if Node = nil then  Exit;
  P := Node.Data;
  if P <> nil then  Dispose(P);
  if Node.HasChildren then begin
    ChildNode := Node.getFirstChild;
    while ChildNode <> nil do begin
      FreeNodeData(ChildNode);
      ChildNode := Node.GetNextChild(ChildNode);
    end;
  end;
end;

//--------------------------------------------------------------------------------
procedure TFrmBaseData_Medicine.FormCreate(Sender: TObject);
begin
  screen.Cursor := crHourGlass;
  AdoqryCommon.Connection := DBWork.AdoconnApplication;
  AdoqryZB.Connection := DBWork.AdoconnApplication;
  AdoqryMX.Connection := DBWork.AdoconnApplication;
  CreateTreeNode_ZClass(TrvData.Items, TrvData.Items[0]);
  TrvData.Items[0].Expand(False);
  TrvData.Selected := TrvData.Items[0];
  screen.Cursor := crDefault;
end;


//--------------------------------------------------------------------------------
procedure TFrmBaseData_Medicine.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  FreeNodeData(TrvData.Items[0]);
  AdoqryCommon.Close;
  AdoqryZB.Close;
  AdoqryMX.Close;
end;


//--------------------------------------------------------------------------------
procedure TFrmBaseData_Medicine.TrvDataExpanding(Sender: TObject;
                                  Node: TTreeNode; var AllowExpansion: Boolean);
var
  P : PTreeNodeLinkData;
begin
  P := Node.Data;
  if P = nil then  Exit;
  if P^.Style = CNm_TreeNodeStyle_MXClass then begin
    if P^.Loaded then  Exit;
    screen.Cursor := crHourGlass;
    CreateTreeNode_Medicine(TrvData.Items, Node);
    screen.Cursor := crDefault;
  end;
end;
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行113.2813毫秒 RSS