2011-12-06 7 views
4

私は、Treeviewを持って、オブジェクトポインタを持つ項目が含まれていると言うことができます。選択したアイテムからオブジェクトが何であるかを判断するにはどうすればアクセスできますか?オブジェクトの種類を特定するにはどうすればよいですか?

ここに、考えを与えるためのクラスとコードの基本的な例を示します。 注:TChildObject1とTChildObject2はTMyObjectから継承します。私は、ツリービューでノードを選択すると

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; 

さて、どのように私はポインタがにつながるオブジェクトのクラスを決定することができます

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 TForm1.TreeView1Click(Sender: TObject); 
var 
    Obj: TMyObject; 
begin 
    if TreeView1.Selected <> nil then 
    begin 
    Obj := TMyObject(TreeView1.Selected.Data); 

    if Obj is TChildObject1 then 
    begin 
     Edit1.Text := 'this node is a child1 object'; 
    end else 
    if Obj is TChildObject2 then 
    begin 
     Edit1.Text := 'and this node is child 2 object'; 
    end; 
    end; 
end; 

私はそれを行うことができ(すなわち、正しいオブジェクトをピックアップしていません)これはエラーではありませんが、それは正しい値を返しません:

注:私は働いていないされ、これを試してみましたが、私は正しい方法だとは思わない以下のようなものは、当然のなど

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; 

のヒントやアドバイスを割り当て、宣言、チェックの多くを意味しています。

答えて

5

主な問題は、ツリービューに追加するオブジェクトのメモリを解放することです。したがって、ノードのデータは無効な場所を指しています。あなたは、各ノードに対してFreeメソッドを呼び出すことができ、データを処分する必要がある場合は、この

Obj := TChildObject1.Create(aName); 
    aTreeView.Items.AddObject(nil, Obj.Name, Obj); 

ようなコードを使用してノードにオブジェクトを割り当てるには

for i:= 0 to TreeView1.Items.Count - 1 do 
begin 
    Obj:= TMyObject(TreeView1.Items.Item[i].Data); 
    if Assigned(Obj) then 
    Obj.Free; 
end; 
+0

+1私は非常に多くのOOPを学習していますが、私はObjを選択したノードのデータに割り当てることができると思っていましたが、あまりにも早く解放しています。 –

+1

@RRUZ: 'TTreeView.OnDeletion'イベントを使用して、ループを使用せずにオブジェクトを解放します。たとえば、次のようにします。' procedure TForm1.TreeView1Deletion(Sender:TObject; Node :TTreeNode); TObject(Node.Data).Free;を開始します。終了; ' –

+0

+1私はOnDeletionイベントを忘れていました:) –

関連する問題