大概意思是,建立一个form,点击左边的treeview,相关的信息就回在右边的DBgirl
显示出来,还要求可以增加记录,修改,删除,保存等功能
例如:
+系统维护(根节点)
    -产品信息(第一层)
         -类别名1(第二层)
              -系列名1(第三层)
                   -详细记录1(最后一层)
                   -详细记录2
                   -详细记录3               -系列名2
              -系列名3
         -类别名2
         -类别名3
    +商场信息
    +销售人员信息
本人只能作到第二层,后面就做不下去,请大家帮帮忙,急着用!!!!

解决方案 »

  1.   

    送你一扁文章看看,可能对你有帮助
     如何初始化一个TreeView? 
    弄一个窗口,放上一个TreeView和一个Button,分别取名为TV1和Btn1。如果需要 
    在每个节点前有个图,请在窗口上放上一个ImageList,取名为ImageList1,双击 
    它,加入六个图标。还要记得记得将TV1的Images属性改为ImageList1噢。双击按 
    钮Btn1,在里面填入以下代码,然后按F9运行,点击Btn1就可以看到效果了。 
    procedure TForm1.Btn1Click(Sender: TObject); 
    Const 
    MyDocDir = 'C:\My Documents'; 
    PersonDir = '3hSoft'; 
    Var 
    Var 
    I : Word; 
    SubNodeName : array [1..5] of ShortString; 
    RootNode, SubNode : TTreeNode; 
    P : PString; 
    begin 
    SubNodeName[1] := '便笺'; 
    SubNodeName[2] := '发件箱'; 
    SubNodeName[3] := '联系人'; 
    SubNodeName[4] := '任务'; 
    SubNodeName[5] := '日记'; 
    TV1.Items.Clear; 
    TV1.Items.BeginUpdate; 
    New(P); 
    P^ := MyDocDir + '\' + PersonDir; 
    RootNode := TV1.Items.AddObject(Nil, '个人文件夹', P); 
    // 此 Node 的图标已对 Images 属性中取第 0 个了。 
    For I := 1 to 5 do 
    begin 
    New(P); 
    P^ := MyDocDir + '\' + PersonDir + '\' + SubNodeName[I]; 
    SubNode := TV1.Items.AddChildObject(RootNode, SubNodeName[I], P) 


    // 如果不想使用图标的话请删除以下两行 
    SubNode.ImageIndex := I; 
    SubNode.SelectedIndex := I; 
    end; 
    TV1.Items.EndUpdate; 
    end; 
    二.在TreeView中如何设置选中结点 
    var 
    i:integer; {i为设置的选中结点的索引值} 
    begin 
    if i>treeview1.items.count then 
    treeview1.items[i].selected:=true; 
    或 
    treeview1.selected:=treeview1.items[i]; 
    三。设置TreeView结点的图形 
    1. 设置TreeView的images属性为已存在的images对象 
    treeview1.images:=imagelist1; 
    2. 在加入结点后执行: 
    var 
    anode:TTreeNode; 
    begein 
    anode:=Treeview1.add(nil,'item1'); 
    anode.imageindex:=0; {结点未选中时显示的图标} 
    anode.selectedindex:=1; {结点选中时显示的图标} 
    end 
    3. 如果结点图形在改变后未发生变化,可以执行: 
    treeview1.refresh; 
    四。如何批量处理TreeView结点 
    使用TreeView的items属性的BeginUpdate和EndUpdate方法,例: 
    TreeView1.items.BeginUpdate; 
    for i:=0 to TreeView1.items.count-1 do 
    begin 
    //将每个结点的文字改成为小写字母 
    TreeView1.items[i].text:=lowercase(TreeView1.items[i].text); 
    end; 
    TreeView1.items.EndUpdate; 五。实现TreeView结点拖拽的实例 
    下面的程序片段演示了如何实现拖拽treeview构件结点的例子 
    {鼠标按下时执行的语句} 
    procedure TForm1.Treeview1MouseDown(Sender: TObject; 
    Button: TMouseButton; Shift: TShiftState; X, Y: Integer); 
    begin 
    {判断左键按下并且鼠标点在一个结点上开始实现拖拽} 
    if ( Button = mbLeft ) and 
    ( htOnItem in Treeview1.GetHitTestInfoAt( X, Y ) ) then 
    begin 
    Treeview1.BeginDrag( False ); 
    end; 
    end; 
    {鼠标拖动执行语句} 
    procedure TForm1.Treeview1DragOver( Sender, Source: TObject; 
    X, Y: Integer; State: TDragState; var Accept: Boolean); 
    var 
    Node : TTreeNode; 
    begin 
    if Source = Treeview1 then 
    begin 
    Node := Treeview1.GetNodeAt( X, Y ); {取当前结点} 
    if Node <> nil then {当前结点不为空才能实现拖拽,accept:=true} 
    Accept := true; 
    end; 
    end; 
    {鼠标释放时执行的语句} 
    procedure TForm1.Treeview1DragDrop( Sender, Source: TObject; 
    X, Y : Integer ); 
    var 
    TempNode : TTreeNode; 
    AttachMode : TNodeAttachMode; 
    begin 
    if Treeview1.Selected = nil then 
    Exit; 
    AttachMode := naAddChild; {设置结点移动模式,设移动结点为子结点} 
    { 注意在这里存在一个bug,当移动结点时,如果目标结点没有子结点,} 
    { 则加入的新的子结点会失败,所以先在当前目标结点的下面 } 
    { 加入一个临时子结点,移动完毕后,再将临时结点删除 } 
    Treeview1.Items.BeginUpdate; 
    try 
    TempNode := Treeview1.Items.AddChild( Treeview1.DropTarget, 
    'Temp' ); 
    try 
    { 移动选中的结点到目标结点 } 
    Treeview1.Selected.MoveTo( Treeview1.DropTarget, AttachMode ); 
    finally 
    TempNode.Free; { 不要忘了释放临时结点 } 
    end; 
    finally 
    Treeview1.Items.EndUpdate; 
    end; 
    end; 
      

  2.   

    我写的一个控件,无限结点任你加。(
    其中有些是我自定义的函数不必过多的追究,你只要掌握思想就OK了,全部贴给你,我懒得整理了。)
    /********************************************************************************/
    unit DBTree;interfaceuses
      Windows, Messages, SysUtils, Classes, Controls, ComCtrls, DB, Menus;type
      TWaxDBTreeView = class(TTreeview)
      private
        FDataSource: TDataSource;
        FNodeFields: String;
        FFieldList: TStringList;
        FieldValueList: TStringList;
        FFiltered: Boolean;
        FBookMarked: Boolean;
        FPopupMenu: TPopupMenu;
        procedure SetDataSource(const Value: TDataSource);
        procedure SetNodeFields(const Value: String);
        function  GetFieldList: TStringList;
        function GetFieldValueList: TStringList;
        procedure SetFiltered(const Value: Boolean);
        procedure SetBookMarked(const Value: Boolean);
        procedure PopupMenuExpandClick(Sender: TObject);
        procedure PopupMenuCollapseClick(Sender: TObject);
        procedure PopupMenuFullExpandClick(Sender: TObject);
        procedure PopupMenuFullCollapseClick(Sender: TObject);
        { Private declarations }
      protected
        { Protected declarations }
        function GetPopupMenu: TPopupMenu; override;
      public
        { Public declarations }
        constructor Create(AOwner: TComponent); override;
        destructor Destroy; override;
        procedure InitTreeView;
        procedure Change(Node: TTreeNode); override;
        procedure Click; override;
        procedure BeforeEdit;
        procedure BeforeDelete;
        procedure AfterDelete;
        procedure AfterInsert;
        procedure AfterPost;
      published
        { Published declarations }
        property DataSource: TDataSource read FDataSource write SetDataSource;
        property NodeFields: String read FNodeFields write SetNodeFields;
        property Filtered: Boolean read FFiltered write SetFiltered  default True;
        property BookMarked: Boolean read FBookMarked write SetBookMarked default True;
      end;procedure Register;implementation
    uses UntWaxPublic, TreeFunc;procedure Register;
    begin
      RegisterComponents('WaxDBTreeview', [TWaxDBTreeView]);
    end;{ TDBTreeView }procedure TWaxDBTreeView.AfterDelete;
    var
      CascadeDeleteLevel: Integer;
    begin
      CascadeDeleteLevel := 0;
      TreeDeleteItem(Self, FieldValueList, CascadeDeleteLevel);
    end;procedure TWaxDBTreeView.AfterInsert;
    begin
      FieldValueList.Clear;
    end;procedure TWaxDBTreeView.AfterPost;
    begin
      items.beginUpdate;  if FieldValueList.count > 0 then TreeDeleteItem(Self, FieldValueList, 0);
      selected := TreeAddItem(Self, GetFieldValueList, FDataSource.DataSet.getbook, True);  items.endUpdate;
    end;procedure TWaxDBTreeView.BeforeDelete;
    begin
      GetFieldValueList;
    end;procedure TWaxDBTreeView.BeforeEdit;
    begin
      GetFieldValueList;
    end;procedure TWaxDBTreeView.Change(Node: TTreeNode);
    begin
      inherited;
      {if FFiltered and (Node.data = nil) then
      begin
        with FDataSource.DataSet do
        begin
          Filtered := False;
          Filter := FFieldList.Strings[Node.level]+'='''+Node.Text+'''';
          Filtered := true;
        end;
      end;
      if Node.data <> nil then
      begin
        if (Node.Parent <> nil) and
           (Node.Parent.Text <> FDataSource.DataSet.FieldByName(FFieldList.Strings[Node.level-1]).AsString)
        then begin
          with FDataSource.DataSet do
          begin
            Filtered := False;
            Filter := FFieldList.Strings[Node.level-1]+'='''+Node.Parent.Text+'''';
            Filtered := true;
          end;
        end;
        FDataSource.DataSet.gotobook(node.data);
      end; }
    end;procedure TWaxDBTreeView.Click;
    var
      Node: TTreeNode;
    begin
      inherited;
      Node := self.Selected;
      if FFiltered and (Node.data = nil) then
      begin
        with FDataSource.DataSet do
        begin
          Filtered := False;
          Filter := FFieldList.Strings[Node.level]+'='''+Node.Text+'''';
          Filtered := true;
        end;
      end;
      if Node.data <> nil then
      begin
        if (Node.Parent <> nil) and
           (Node.Parent.Text <> FDataSource.DataSet.FieldByName(FFieldList.Strings[Node.level-1]).AsString)
        then begin
          with FDataSource.DataSet do
          begin
            Filtered := False;
            Filter := FFieldList.Strings[Node.level-1]+'='''+Node.Parent.Text+'''';
            Filtered := true;
          end;
        end;
        FDataSource.DataSet.gotobook(node.data);
      end;
    end;constructor TWaxDBTreeView.Create(AOwner: TComponent);
    begin
      inherited;
      FFieldList := TStringList.Create;
      FieldValueList := TStringList.Create;
      FFiltered := True;
      FBookMarked := True;
      ReadOnly := True;
    end;destructor TWaxDBTreeView.Destroy;
    begin
      FieldValueList.Free;
      FFieldList.Free;
      inherited;
    end;function TWaxDBTreeView.GetFieldList: TStringList;
    begin
      Result := nil;  if trim(FNodeFields) = '' then
      begin
        SystemError('EMPTY_NODE_FIELDS',MB_OK);
        Exit;
      end;  FFieldList := ExtractBySep(FNodeFields, ',');
      Result := FFieldList;
    end;function TWaxDBTreeView.GetFieldValueList: TStringList;
    var
      I: Integer;
    begin
      GetFieldList;
      FieldValueList.Clear;  for I := 0 to FFieldList.Count - 1 do
      begin
        FieldValueList.Add(FDataSource.DataSet.FieldByName(FFieldList.Strings[I]).AsString);
      end;  Result := FieldValueList;
    end;function TWaxDBTreeView.GetPopupMenu: TPopupMenu;
      procedure AddMenu(Caption: String; ANotifyEvent: TNotifyEvent);
      var
        AMenuItem: TMenuItem;
      begin
        AMenuItem := TMenuItem.Create(FPopupMenu);
        AMenuItem.Caption := Caption;
        AMenuItem.OnClick := ANotifyEvent;
        FPopupMenu.Items.Add(AMenuItem);
      end;
    begin
      if Assigned(FPopupMenu) then
        FPopupMenu.Free;  FPopupMenu := TPopupMenu.Create(Self);
      FPopupMenu.AutoPopup := True;
      FPopupMenu.AutoHotkeys := maManual;
      FPopupMenu.AutoLineReduction := maManual;
      if LoadStrFromMainForm('TREEVIEW_POPUPMENU_EXPAND') <> '' then
        AddMenu(LoadStrFromMainForm('TREEVIEW_POPUPMENU_EXPAND'), PopupMenuExpandClick)
      else
        AddMenu('展开(&E)', PopupMenuExpandClick);  if LoadStrFromMainForm('TREEVIEW_POPUPMENU_COLLAPSE') <> '' then
        AddMenu(LoadStrFromMainForm('TREEVIEW_POPUPMENU_COLLAPSE'), PopupMenuCollapseClick)
      else
        AddMenu('收拢(&C)', PopupMenuCollapseClick);  if LoadStrFromMainForm('TREEVIEW_POPUPMENU_FULLEXPAND') <> '' then
        AddMenu(LoadStrFromMainForm('TREEVIEW_POPUPMENU_FULLEXPAND'), PopupMenuFullExpandClick)
      else
        AddMenu('全部展开(&F)', PopupMenuFullExpandClick);  if LoadStrFromMainForm('TREEVIEW_POPUPMENU_FULLCOLLAPSE') <> '' then
        AddMenu(LoadStrFromMainForm('TREEVIEW_POPUPMENU_FULLCOLLAPSE'), PopupMenuFullCollapseClick)
      else
        AddMenu('全部收拢(&P)', PopupMenuFullCollapseClick);
      Result := FPopupMenu;
    end;
      

  3.   

    procedure TWaxDBTreeView.InitTreeView;
    begin
      if not Assigned(FDataSource) then
      begin
        SystemError('NOT_ASSIGN_DATASOURCE',MB_OK);
        Exit;
      end;  Items.BeginUpdate;  with FDataSource.DataSet do
      begin
        if not Active then Active := true;
        First;
        while not Eof do
        begin
          GetFieldValueList;
          TreeFunc.TreeAddItem(Self, FieldValueList, getBook, false);
          Next;
        end;
      end;  Alphasort;
      Items.EndUpdate;
    end;procedure TWaxDBTreeView.PopupMenuCollapseClick(Sender: TObject);
    begin
      if (Selected <> nil) then
        Selected.Collapse(True)
    end;procedure TWaxDBTreeView.PopupMenuExpandClick(Sender: TObject);
    begin
      if (Selected <> nil) then
        Selected.Expand(True)
    end;procedure TWaxDBTreeView.PopupMenuFullCollapseClick(Sender: TObject);
    begin
        FullCollapse
    end;procedure TWaxDBTreeView.PopupMenuFullExpandClick(Sender: TObject);
    begin
        FullExpand
    end;procedure TWaxDBTreeView.SetBookMarked(const Value: Boolean);
    begin
      FBookMarked := Value;
      if not FBookMarked then
        FFiltered := True;
    end;procedure TWaxDBTreeView.SetDataSource(const Value: TDataSource);
    begin
      FDataSource := Value;
    end;procedure TWaxDBTreeView.SetFiltered(const Value: Boolean);
    begin
      FFiltered := Value or (not FBookMarked);
    end;procedure TWaxDBTreeView.SetNodeFields(const Value: String);
    begin
      FNodeFields := Value;
    end;end.
      

  4.   

    unit TreeFunc;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, ComCtrls, DB, Forms, Dialogs, DBTree;function  TreeFindItem(Sender: TWaxDBTreeView; NodeItem: TTreeNode; Name: String): TTreeNode;
    function  TreeAddItem(Sender: TWaxDBTreeView; ItemList: TStrings; Book: TBook; Resort: Boolean): TTreeNode;
    function  TreeGetItem(Sender: TWaxDBTreeView; ItemList: TStrings): TTreeNode;
    procedure TreeDeleteItem(Sender: TWaxDBTreeView; ItemList: TStrings; Level: Integer);implementation
    function TreeAddItem(Sender: TWaxDBTreeView; ItemList: TStrings; Book: TBook; Resort: Boolean): TTreeNode;
    var
       ThisNode, Node: TTreeNode;
       I: Integer;
    begin
      Node := nil;
      for I := 0 to Itemlist.count -1 do
      begin
        ThisNode := TreeFindItem(Sender, node, Itemlist[i]);
        if ThisNode <> nil then Node := ThisNode else
        begin
          if (not Sender.BookMarked) or (I < Itemlist.count -1) then
          begin
            if I = 0 then Node := Sender.items.Add(Node, Itemlist[i])
            else Node := Sender.items.AddChild(Node, Itemlist[i]);
          end else
          begin
            if I = 0 then Node := Sender.items.AddObject(Node, Itemlist[i], Book)
            else Node := Sender.items.AddChildObject(Node, Itemlist[i], Book);
          end;
          if Resort and (Node.parent <> nil) then Node.parent.alphasort;
          Node.ImageIndex := 0 ;
          Node.SelectedIndex := 1;
        end;
      end;
      Result := Node;
    end;function TreeFindItem(Sender: TWaxDBTreeView; NodeItem: TTreeNode; Name: String): TTreeNode;
    begin
      if NodeItem = nil then NodeItem := Sender.items.getfirstnode
      else NodeItem := NodeItem.getfirstchild;  if (NodeItem <> nil) and (NodeItem.text <> Name) then
      repeat
            NodeItem := NodeItem.getnextsibling;
      until (NodeItem = nil) or (NodeItem.text = Name);
      Result := NodeItem;
    end;function TreeGetItem(Sender: TWaxDBTreeView; ItemList: TStrings): TTreeNode;
    begin
      Result := TreeAddItem(Sender, Itemlist, nil, false);
    end;procedure TreeDeleteItem(Sender: TWaxDBTreeView; ItemList: TStrings; Level: Integer);
    var
       Node, Parent: TTreeNode;
    begin
      Node := TreeGetItem(Sender, ItemList);
      while Node.level >= Level do
      begin
        Parent := Node.parent;
        Node.delete;
        if (Parent = nil) or (Parent.hasChildren) then break;
        Node := Parent;
      end;
    end;end.
      

  5.   

    不论父与子,每个节点就是一个node,搞清楚parent与child的关系就可以了,动手试试,很简单的.