Delphi 如何识别对象类型?
假设我有一个树状视图,它包含带有对象指针的项。如何从所选项目确定对象是什么,以便访问它 下面是一些类和代码的基本示例,让我们了解一下: 注意:TChildObject1和TChildObject2继承自TMyObjectDelphi 如何识别对象类型?,delphi,oop,pointers,Delphi,Oop,Pointers,假设我有一个树状视图,它包含带有对象指针的项。如何从所选项目确定对象是什么,以便访问它 下面是一些类和代码的基本示例,让我们了解一下: 注意:TChildObject1和TChildObject2继承自TMyObject type TMyObject = class private FName: string; public property Name: string read FName write FName; constructor Create(aN
type
TMyObject = class
private
FName: string;
public
property Name: string read FName write FName;
constructor Create(aName: string);
end;
type
TChildObject1 = class(TMyObject)
private
FSomeString: string;
public
property SomeString: string read FSomeString write FSomeString;
constructor Create(aName: string);
destructor Destroy; override;
end;
type
TChildObject2 = class(TMyObject)
private
FSomeInteger: integer;
public
property SomeInteger: integer read FSomeInteger write FSomeInteger;
constructor Create(aName: string);
destructor Destroy; override;
end;
假设它们是创建并添加到TTreeview的,如下所示:
procedure NewChild1(aTreeView: TTreeView; aName: string);
var
Obj: TChildObject1;
begin
Obj := TChildObject1.Create(aName);
try
aTreeView.Items.AddObject(nil, Obj.Name, Obj);
finally
Obj.Free;
end;
end;
procedure NewChild2(aTreeView: TTreeView; aName: string);
var
Obj: TChildObject2;
begin
Obj := TChildObject2.Create(aName);
try
aTreeView.Items.AddObject(nil, Obj.Name, Obj);
finally
Obj.Free;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
// add the items to the tree
NewChild1(TreeView1, 'Child Object 1');
NewChild2(TreeView1, 'Child Object 2');
end;
现在,当我在树视图中选择一个节点时,如何确定指针指向哪个对象类?我试过这个,但不起作用:
注意:这不会出错,但不会返回正确的值(即,不会拾取正确的对象)
过程TForm1.treeview1单击(发送方:TObject);
变量
对象:TMyObject;
开始
如果TreeView1.选择了nil,则
开始
对象:=TMyObject(TreeView1.Selected.Data);
如果Obj是TChildObject1,则
开始
Edit1.Text:=“此节点是一个child1对象”;
结束其他
如果Obj是TChildObject2,则
开始
Edit1.Text:='且该节点为子2对象';
结束;
结束;
结束;
我可以像下面这样做,但我认为这不是正确的方法,它意味着大量的检查、声明、分配等
procedure TForm1.TreeView1Click(Sender: TObject);
var
ChildObj1: TChildObject1;
ChildObj2: TChildObject2;
begin
if TreeView1.Selected <> nil then
begin
if TreeView1.Selected.Text = 'Child Object 1' then
begin
ChildObj1 := TreeView1.Selected.Data;
Edit1.Text := ChildObj1.SomeString;
end else
if TreeView1.Selected.Text = 'Child Object 2' then
begin
ChildObj2 := TreeView1.Selected.Data;
Edit1.Text := IntToStr(ChildObj2.SomeInteger);
end;
end;
end;
过程TForm1.treeview1单击(发送方:TObject);
变量
ChildObj1:TChildObject1;
ChildObj2:TChildObject2;
开始
如果TreeView1.选择了nil,则
开始
如果TreeView1.Selected.Text='Child Object 1',则
开始
ChildObj1:=TreeView1.Selected.Data;
Edit1.Text:=ChildObj1.SomeString;
结束其他
如果TreeView1.Selected.Text='Child Object 2',则
开始
ChildObj2:=TreeView1.Selected.Data;
Edit1.Text:=IntToStr(ChildObj2.SomeInteger);
结束;
结束;
结束;
感谢您的提示和建议。主要问题是您正在释放要添加到treeview的对象的内存。因此,节点的数据指向无效位置 要将对象指定给节点,请使用如下代码
Obj := TChildObject1.Create(aName);
aTreeView.Items.AddObject(nil, Obj.Name, Obj);
当需要处理数据时,可以为每个节点调用Free
方法
for i:= 0 to TreeView1.Items.Count - 1 do
begin
Obj:= TMyObject(TreeView1.Items.Item[i].Data);
if Assigned(Obj) then
Obj.Free;
end;
+1我正在学习OOP,出于某种原因,我认为我可以将Obj分配给所选的节点数据,但我想不会,我释放它太早了。刚刚编辑了我的代码,它现在识别了正确的对象:)@RRUZ:我将使用
TTreeView.OnDeletion
事件来释放对象,而不是使用循环,例如:procedure TForm1.TreeView1删除(发送方:ToObject;节点:TTreeNode);开始对象(Node.Data).Free;结束代码>
for i:= 0 to TreeView1.Items.Count - 1 do
begin
Obj:= TMyObject(TreeView1.Items.Item[i].Data);
if Assigned(Obj) then
Obj.Free;
end;