我正在使用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, Edit1.Text + ' ' + IntToStr(Round(Random(1000))), 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.Index), 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;