加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 如何从TTreeView中删除节点及其对象

发布时间:2020-12-15 09:07:33 所属栏目:大数据 来源:网络整理
导读:我正在使用Delphi 10 Starter版.我正在研究如何使用Delphi的TTreeView组件. 一切正常,没有问题.我留下的唯一问题是: 将对象添加到节点后,删除项及其对象的正确方法是什么? 这是我的代码(参见Button6Click): type TMyNode2 = class public nom: Integer; c
我正在使用Delphi 10 Starter版.我正在研究如何使用Delphi的TTreeView组件.

一切正常,没有问题.我留下的唯一问题是:

将对象添加到节点后,删除项及其对象的正确方法是什么?

这是我的代码(参见Button6Click):

type
  TMyNode2 = class
  public
    nom: Integer;
    comm: String;
  end;

var
  Form1: TForm1;
  MyNode2: TMyNode2;

procedure TForm1.Button1Click(Sender: TObject); // add node
var
  x: TTreeNode;
begin
  x := tv1.Items.Add(tv1.Selected,Edit1.Text + ' ' + IntToStr(Round(Random(100))));
  x.ImageIndex := 1;
  x.SelectedIndex := x.ImageIndex;
  x.StateIndex := x.ImageIndex;
end;

procedure TForm1.Button4Click(Sender: TObject); // add child node
var
  x: TTreeNode;
begin
  x := tv1.Items.AddChild(tv1.Selected,'Child ' + Edit1.Text + ' ' + IntToStr(Round(Random(100))));
  x.ImageIndex := 2;
  x.SelectedIndex := x.ImageIndex;
  x.StateIndex := x.ImageIndex;
  tv1.Selected.Expand(true);
  x.Selected := true;
  x.Expand(true);
end;

procedure TForm1.Button2Click(Sender: TObject); // del node (if not 1st)
var
  x,y: TTreeNode;
begin
  y := tv1.Items[0];
  x := tv1.Selected;
  if x <> y then
    x.Delete
  else
    ShowMessage('Do not del 1st node!');
end;

procedure TForm1.Button3Click(Sender: TObject); // add node (v.2 as object)
var
  x: TTreeNode;
begin
  MyNode2 := TMyNode2.Create;
  MyNode2.nom := Round(Random(1000));
  MyNode2.comm := IntToStr(MyNode2.nom) + ' comment ' + IntToStr(MyNode2.nom);
  x := tv1.Items.AddObject(tv1.Selected,Edit1.Text + ' ' + IntToStr(Round(Random(1000))),Pointer(MyNode2)); 
  x.ImageIndex := 3;
  x.SelectedIndex := x.ImageIndex;
  x.StateIndex := x.ImageIndex;
  tv1.Selected.Expand(true);
  x.Selected := true;
  x.Expand(true);
end;

procedure TForm1.Button5Click(Sender: TObject); // add child node (v.2 as object)
var
  x: TTreeNode;
begin
  MyNode2 := TMyNode2.Create;
  MyNode2.nom := Round(Random(1000));
  MyNode2.comm := IntToStr(MyNode2.nom) + ' child comment ' + IntToStr(MyNode2.nom);
  x := tv1.Items.AddChildObject(tv1.Selected,Pointer(MyNode2));
  x.ImageIndex := 4;
  x.SelectedIndex := x.ImageIndex;
  x.StateIndex := x.ImageIndex;
  tv1.Selected.Expand(true);
  x.Selected := true;
  x.Expand(true);
end;

procedure TForm1.Button6Click(Sender: TObject); // del node (if not 1st) and "as" object
var
  x,y: TTreeNode;
begin
  y := tv1.Items[0];
  x := tv1.Selected;
  if x <> y then begin
    //class(x.tMyNode2(node.Data)).Free; // **** // !!!!!!!!!!!!!!!
    x.Delete;
  end else
    ShowMessage('Do not del 1st node!');
end;

procedure TForm1.FormCreate(Sender: TObject); // on create - add data 2 1st node
var
  x: TTreeNode;
begin
  MyNode2 := TMyNode2.Create;
  MyNode2.nom := 100001;
  MyNode2.comm := '1st node comment';
  x := tv1.Items[0];
  x.Data := Pointer(MyNode2);
end;

procedure TForm1.tv1Change(Sender: TObject; Node: TTreeNode); // look node prop.
begin
  if Node = nil then
    Caption:='Not select'
  else
  if Node.Data = nil then
    Caption := Format('Nom: %d,Im.Ind: %d',[Integer(Node.Index),Integer(Node.ImageIndex)])
  else
    Caption := Format('Nom: %d,Im.Ind: %d,MyNode.Nom: %d,Comm: %s',Integer(Node.ImageIndex),Integer(TMyNode2(node.Data).nom),string(TMyNode2(node.Data).comm)]);
end;

解决方法

使用TreeView的OnDeletion事件,该事件在从树中删除TTreeNode时触发:

procedure TForm1.tv1Deletion(Sender: TObject; Node: TTreeNode);
begin
  TMyNode2(Node.Data).Free;
  // or simply:
  // TObject(Node.Data).Free;
end;

从而:

procedure TForm1.Button2Click(Sender: TObject);
// del node (if not 1st)
var
  x,y: TTreeNode;
begin
  x := tv1.Selected;
  if x <> nil then
  begin
    y := tv1.Items.GetFirstNode;
    if x <> y then
      x.Delete
    else
      ShowMessage('Do not del 1st node!');
  end;
end;

procedure TForm1.Button6Click(Sender: TObject);
// del node (if not 1st) and its object
var
  x,y: TTreeNode;
begin
  x := tv1.Selected;
  if x <> nil then
  begin
    y := tv1.Items.GetFirstNode;
    if x <> y then
      x.Delete
    else
      ShowMessage('Do not del 1st node!');
  end;
end;

如您所见,Button2Click()和Button6Click()现在完全相同,因此您可以删除其中一个.除非你真的希望Button2Click()不释放节点的对象,在这种情况下你可以在调用x.Delete()之前将x.Data设置为nil(你仍然负责跟踪对象,以便你可以释放它以后,否则它会被泄露):

procedure TForm1.Button2Click(Sender: TObject);
// del node (if not 1st) but not its object
var
  x,y: TTreeNode;
begin
  x := tv1.Selected;
  if x <> nil then
  begin
    y := tv1.Items.GetFirstNode;
    if x <> y then
    begin
      x.Data := nil; // <-- !!!
      x.Delete;
    end else
      ShowMessage('Do not del 1st node!');
  end;
end;

procedure TForm1.Button6Click(Sender: TObject);
// del node (if not 1st) and its object
var
  x,y: TTreeNode;
begin
  x := tv1.Selected;
  if x <> nil then
  begin
    y := tv1.Items.GetFirstNode;
    if x <> y then
      x.Delete
    else
      ShowMessage('Do not del 1st node!');
  end;
end;

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读