在TreeView中我知道一个节点的值,那么如何删掉其他的节点,只保留这个节点(如果这个节点有父节点或者子节点都应该保留!)。不知我描述的是否清楚,在线!!

解决方案 »

  1.   

    先获取该节点的FullPath属性,再遍历整个树,将与该节点无关的节点都删除。
      

  2.   

    TO:bluesky23(乐天) 
    兄弟能够给点代码?
      

  3.   

    用一个for检查每一个节点进行判断
      

  4.   

    TO:rayd(ray) 
    怎么个判断法?
      

  5.   

    假定结点的值为'Text'procedure TForm1.Button1Click(Sender: TObject);
    var
      i, j, k,
      Node_Count,    //根结点的个数
      Current_Node_Level,
      Next_Node_Level: integer;
      Delete_Flag :Boolean; //删除标记
    begin
      Node_Count := 0;
      for i := 0 to TreeView1.Items.Count -1 do
        begin
          if TreeView1.Items.Item[i].level = 0 then
            Inc(Node_Count);
        end;  if Node_Count = 0 then
        begin
          ShowMessage('该树没有任何结点!');
          Exit;
        end;  //遍历每一层根结点下的子树,若找不到符合要求的结点便删除该根结点
      for i := 1 to Node_Count do
        for j := 0 to TreeView1.Items.Count - 1 do
          begin
            if TreeView1.Items.Item[j].Level = 0 then
              begin
                k := j;
                Delete_Flag := False;
                repeat
                if TreeView1.Items.Item[k].Text = 'Text' then
                  begin
                    Delete_Flag := True;
                    Break;
                  end;
                if TreeView1.Items.Item[k].getFirstChild = NIL then Break;
                Current_Node_Level := TreeView1.Items.Item[k].Level;
                Next_Node_Level := TreeView1.Items.Item[k + 1].Level;
                Inc(k);
                until Next_Node_Level < Current_Node_Level;
                if not Delete_Flag then TreeView1.Items.Item[j].Delete;
              end;
             Break;
          end;
    end;算法有点冗长,有待优化,但还是可以行的通的
      

  6.   

    非常感谢 luke5678(~类~) 的代码支持!试试先
      

  7.   

    luke5678(~类~) :
    兄弟结果不对呀!
      

  8.   

    TO:Linux2001(恋人不如自恋)
    不妨将你的代码贴上!谢谢
      

  9.   

    risingsoft(一苇渡江):非常感谢!
      

  10.   

    这样的东西很容易实现啊,楼主你应该先自己多想想,这种问题只是编程中的基础问题,我给你思路,代码自己写咯!
    简单的办法,声明一个TTreeNode的动态数组,然后对整个TTreeView进行遍历,因为你需要保留的节点你是知道的,那么就遍历TTreeView的时候,如果找到这个节点,那么你就可以得到这个节点的所有父亲节点,这样,你这个时候再动态的设定动态数组的Length,然后把每个父亲节点和本身存放到这个动态数组中,然后进行第二次遍历,然后把每个节点和动态数组中存放的节点进行比较,如果相同,就不删除,否则就删除!这个是非常简单的一种方法,速度不是太快,如果节点量很少,少于100个,那么速度还是非常快的!
      

  11.   

    这样的东西很容易实现啊,楼主你应该先自己多想想,这种问题只是编程中的基础问题,我给你思路,代码自己写咯!
    简单的办法,声明一个TTreeNode的动态数组,然后对整个TTreeView进行遍历,因为你需要保留的节点你是知道的,那么就遍历TTreeView的时候,如果找到这个节点,那么你就可以得到这个节点的所有父亲节点,这样,你这个时候再动态的设定动态数组的Length,然后把每个父亲节点和本身存放到这个动态数组中,然后进行第二次遍历,然后把每个节点和动态数组中存放的节点进行比较,如果相同,就不删除,否则就删除!这个是非常简单的一种方法,速度不是太快,如果节点量很少,少于100个,那么速度还是非常快的!
      

  12.   

    procedure TForm1.Button1Click(Sender: TObject);
    var
      i : Integer;
      Node : TTreeNode;
    begin
      Node := TV.Selected; //你要保留的node
      for i := TV.Items.Count - 1 downto 0 do
        if not ((TV.Items[i]=node) or (Node.HasAsParent(TV.Items[i]))) then
          TV.Items.Delete(TV.Items[i]);
    end;
      

  13.   

    to:risingsoft(一苇渡江) 
    你分析的完全正确!谢谢!
      

  14.   

    TO:Linux2001(恋人不如自恋)
    兄弟讲的很有道理,方法我调试了很长时间,结果还是有错,兄弟能否将你的算法贴出来,让我学习学习!
      

  15.   

    1、创建一工程文件。命名如下
       main:          TForm               主界面
       tvMain:        TTreeView           主界面树控件
       btnAddNode:    TButton             增加节点
       btnAddSubNode: TButton             增加子节点
       btnDelNode:    TButton             删除节点(核心功能)2、完整代码如下
     
    unit MainP;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      StdCtrls, ComCtrls;type
      PMyData=^TMyData;
      TMyData=record
        ID,             //唯一编号
        Val,            //值
        Flag: string;   //标志
      end;type
      TMain = class(TForm)
        tvMain: TTreeView;
        btnAddNode: TButton;
        btnDelNode: TButton;
        btnAddSubNode: TButton;
        procedure btnAddNodeClick(Sender: TObject);
        procedure btnAddSubNodeClick(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure btnDelNodeClick(Sender: TObject);
      private
        { Private declarations }
        NodeValue: integer;
      public
        { Public declarations }
        function GetNodeID: String;
      end;var
      Main: TMain;implementation{$R *.DFM}procedure TMain.btnAddNodeClick(Sender: TObject);
    var
      newNode,curNode: TTreeNode;
      ptrData: PMyData;
    begin
      (*获取父节点,为增加同级节点做好准备*)
      curNode := tvMain.Selected;
      if curNode <> nil then
        curNode := curNode.Parent;  (*增加节点*)
      ptrData := new(PMyData);
      ptrData^.ID   := GetNodeID;
      ptrData^.Val  := ptrData^.ID;
      ptrData^.Flag := 'F';  newNode := tvMain.Items.AddChildObject(curNode,ptrData^.Val,ptrData);
    end;procedure TMain.btnAddSubNodeClick(Sender: TObject);
    var
      newNode,curNode: TTreeNode;
      ptrData: PMyData;
    begin
      (*获取父节点,为增加同级节点做好准备*)
      curNode := tvMain.Selected;  (*增加节点*)
      ptrData := new(PMyData);
      ptrData^.ID   := GetNodeID;
      ptrData^.Val  := ptrData^.ID;
      ptrData^.Flag := 'F';  newNode := tvMain.Items.AddChildObject(curNode,ptrData^.Val,ptrData);
    end;procedure TMain.FormCreate(Sender: TObject);
    begin
      NodeValue := 1;
    end;function TMain.GetNodeID: String;
    begin
      Result := IntToStr(NodeValue);
      Inc(NodeValue);
    end;procedure TMain.btnDelNodeClick(Sender: TObject);
      function FindNode(var tree: TTreeView; NodeValue: String): TTreeNode;
      var
        i: Integer;
        curNode: TTreeNode;
        ptrData: PMyData;
      begin
        Result := Nil;
        for i := 0 to tree.Items.Count - 1 do
        begin
          curNode := tree.Items[i];
          ptrData := PMyData(curNode.Data);
          if ptrData^.Val = NodeValue then
          begin
            Result := curNode;
            Break;
          end;
        end;
      end;  function DeleteNode(var tree: TTreeView; var Node: TTreeNode): Boolean;
      var
        oldNode: TTreeNode;    i: integer;
      begin
        oldNode := Node;    for i := tree.Items.Count - 1 downto 0 do
        begin
          if Not( (tree.Items[i].ItemId = Node.ItemId) or
                  (Node.HasAsParent(tree.Items[i])) or
                  (tree.Items[i].Level > Node.Level)
                ) then
          begin
            tree.Items.Delete(tree.Items[i]);
          end;
        end;    tree.Selected := oldNode;
      end;var
      lsNodeValue: String;  curNode: TTreeNode;
    begin
      lsNodeValue := IntToStr(NodeValue);
      if not InputQuery('  信息:删除节点  ','  提示:请输入要删除节点的值  ',lsNodeValue) then exit;  curNode := FindNode(tvMain,lsNodeValue);
      if curNode <> nil then
      begin
        tvMain.Selected := curNode;
        if MessageDlg('  提示:确定删除该节点吗?  ',mtConfirmation,[mbYES,mbNO],0) <> mrYES then exit;    DeleteNode(tvMain,curNode);
        ShowMessage('  信息:节点删除完毕!  ');
      end
      else
      begin
        ShowMessage('  信息:您输入的节点值不存在!  ');
      end;
    end;end.  
      

  16.   

    TO:risingsoft(一苇渡江)
    正在测试。先谢谢!
      

  17.   

    TO:risingsoft(一苇渡江)
    兄弟你的方法完全正确!
    现在我还有个小小的变化:如果对这个树Treeview我想同时删除的不止一个节点,如果同时删除多个节点,程序应该怎么变化一下!不好意思,再向你讨教!谢谢
      

  18.   

    大家也可以根据risingsoft(一苇渡江)的方法,想想怎么同时保留的不止一个节点,如果同时保留多个节点,程序应该怎么变化一下!
      

  19.   

    unit MainP;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      StdCtrls, ComCtrls;type
      PMyData=^TMyData;
      TMyData=record
        ID,             //唯一编号
        Val,            //值
        Flag: string;   //标志
      end;type
      TMain = class(TForm)
        tvMain: TTreeView;
        btnAddNode: TButton;
        btnDelNode: TButton;
        btnAddSubNode: TButton;
        btnDelMNode: TButton;
        procedure btnAddNodeClick(Sender: TObject);
        procedure btnAddSubNodeClick(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure btnDelNodeClick(Sender: TObject);
        procedure btnDelMNodeClick(Sender: TObject);
      private
        { Private declarations }
        NodeValue: integer;
      public
        { Public declarations }
        function GetNodeID: String;
      end;
      function FindNode(var tree: TTreeView; NodeValue: String): TTreeNode;
      function DeleteNode(var tree: TTreeView; var Node: TTreeNode): Boolean;
      function DeleteMNode(var tree: TTreeView; var Nodes: array of TTreeNode): Boolean;var
      Main: TMain;implementation{$R *.DFM}function FindNode(var tree: TTreeView; NodeValue: String): TTreeNode;
    var
      i: Integer;
      curNode: TTreeNode;
      ptrData: PMyData;
    begin
      Result := Nil;
      for i := 0 to tree.Items.Count - 1 do
      begin
        curNode := tree.Items[i];
        ptrData := PMyData(curNode.Data);
        if ptrData^.Val = NodeValue then
        begin
          Result := curNode;
          Break;
        end;
      end;
    end;function DeleteNode(var tree: TTreeView; var Node: TTreeNode): Boolean;
    var
      oldNode: TTreeNode;  i: integer;
    begin
      oldNode := Node;  for i := tree.Items.Count - 1 downto 0 do
      begin
        if Not( (tree.Items[i].ItemId = Node.ItemId) or
                (Node.HasAsParent(tree.Items[i])) or
                ((tree.Items[i].Level > Node.Level) and (tree.Items[i].HasAsParent(Node)))
              ) then
        begin
          tree.Items.Delete(tree.Items[i]);
        end;
      end;  tree.Selected := oldNode;
    end;function DeleteMNode(var tree: TTreeView; var Nodes: array of TTreeNode): Boolean;
    var
      i,                          //循环变量,遍历整个TTreeView
      j: integer;                 //循环变量,遍欲保留动态节点数组  lbFlag,                     //比较标志
      FirstFlag: Boolean;         //初次比较标志,为了给lbFlag赋初值
    begin  (*遍历树目录*)
      for i := tree.Items.Count - 1 downto 0 do
      begin
        (*对某一节点比较时,初始化初次比较标志*)
        FirstFlag := True;
        (*遍历欲保留动态节点数组*)
        for j := Low(Nodes) to High(Nodes) do
        begin
          (*非空进行比较*)
          if Nodes[j] <> nil then
          begin
            (*初次比较,给lbFlag赋初值*)
            if FirstFlag then
            begin
              FirstFlag := False;
              lbFlag :=
                    (tree.Items[i].ItemId = Nodes[j].ItemId) or
                    (Nodes[j].HasAsParent(tree.Items[i])) or
                    ( (tree.Items[i].Level > Nodes[j].Level) and
                      (tree.Items[i].HasAsParent(Nodes[j])) );
            end
            else
            (*非初次比较,进行逻辑值合并*)
            begin
              lbFlag := lbFlag or
                    (tree.Items[i].ItemId = Nodes[j].ItemId) or
                    (Nodes[j].HasAsParent(tree.Items[i])) or
                    ( (tree.Items[i].Level > Nodes[j].Level) and
                      (tree.Items[i].HasAsParent(Nodes[j])) );
            end;      end;
        end;    (*判断删除*)
        if (Not lbFlag) and (Not FirstFlag) then
        begin
          tree.Items.Delete(tree.Items[i]);
        end;
      end;
    end;procedure TMain.btnAddNodeClick(Sender: TObject);
    var
      newNode,curNode: TTreeNode;
      ptrData: PMyData;
    begin
      (*获取父节点,为增加同级节点做好准备*)
      curNode := tvMain.Selected;
      if curNode <> nil then
        curNode := curNode.Parent;  (*增加节点*)
      ptrData := new(PMyData);
      ptrData^.ID   := GetNodeID;
      ptrData^.Val  := ptrData^.ID;
      ptrData^.Flag := 'F';  newNode := tvMain.Items.AddChildObject(curNode,ptrData^.Val,ptrData);
    end;procedure TMain.btnAddSubNodeClick(Sender: TObject);
    var
      newNode,curNode: TTreeNode;
      ptrData: PMyData;
    begin
      (*获取父节点,为增加同级节点做好准备*)
      curNode := tvMain.Selected;  (*增加节点*)
      ptrData := new(PMyData);
      ptrData^.ID   := GetNodeID;
      ptrData^.Val  := ptrData^.ID;
      ptrData^.Flag := 'F';  newNode := tvMain.Items.AddChildObject(curNode,ptrData^.Val,ptrData);
    end;procedure TMain.FormCreate(Sender: TObject);
    begin
      NodeValue := 1;
    end;function TMain.GetNodeID: String;
    begin
      Result := IntToStr(NodeValue);
      Inc(NodeValue);
    end;procedure TMain.btnDelNodeClick(Sender: TObject);
    var
      lsNodeValue: String;  curNode: TTreeNode;
    begin
      lsNodeValue := IntToStr(NodeValue);
      if not InputQuery('  删除节点:  ','  请输入要删除节点的值...  ',lsNodeValue) then exit;  curNode := FindNode(tvMain,lsNodeValue);
      if curNode <> nil then
      begin
        tvMain.Selected := curNode;
        if MessageDlg('  提示:确定删除该节点吗?  ',mtConfirmation,[mbYES,mbNO],0) <> mrYES then exit;    DeleteNode(tvMain,curNode);
        ShowMessage('  信息:节点删除完毕!  ');
      end
      else
      begin
        ShowMessage('  信息:您输入的节点值不存在!  ');
      end;
    end;procedure TMain.btnDelMNodeClick(Sender: TObject);
    var
      Nodes: array of TTreeNode;  lsNodeValue: String;  curNode: TTreeNode;
    begin
      lsNodeValue := '';
      SetLength(Nodes,0);
      while InputQuery('  删除节点:  ','  请输入要删除节点的值...  ',lsNodeValue) do
      begin
        curNode := FindNode(tvMain,lsNodeValue);
        if curNode <> nil then
        begin
          SetLength(Nodes, High(Nodes)+2);
          Nodes[High(Nodes)] := curNode;
        end;
        lsNodeValue := '';
      end;
      if Length(Nodes) > 0 then
        DeleteMNode(tvMain, Nodes);
    end;end.