ツリーノードのデータについて

解決


質問者  2004-08-15 21:33:31  No: 10418  IP: 192.*.*.*

ツリービューの親フォームを変更するとノードのデータがおかしくなるのですが何故でしょうか?
教えていただけますか?

編集 削除
LupinⅢ  URL  2004-08-16 11:28:51  No: 10419  IP: 192.*.*.*

もう少し詳しく書いて頂いた方がレスが付くと思いますよ。

編集 削除
質問者  2004-08-16 14:10:37  No: 10420  IP: 192.*.*.*

TTreeviewのItems[i]のTNodeのDateにPStringを関連付けたのですがTTreeViewのParentを変更すると、PString(Node.Data)の値が参照できなくなります
ご教授お願します

編集 削除
にしの  2004-08-16 14:32:03  No: 10421  IP: 192.*.*.*

PCHARにして、バッファを確保して文字列を入れてみてください。
OnDeletionイベントで解放するようにしておくと、けっこう簡単に実装できると思います。

編集 削除
LupinⅢ  URL  2004-08-16 14:32:49  No: 10422  IP: 192.*.*.*

パネルをフォームに一つ置き、
ボタンを2つフォームに置きます。

下記のコードを挿入して実行したところ、Dataプロパティも読み込めました。

  private
    { Private 宣言 }
    SL:TStringList;
  public
    { Public 宣言 }

  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.TreeView1Click(Sender: TObject);
begin
  ShowMessage(String( TreeView1.Selected.Data))
end;

procedure TForm1.Button1Click(Sender: TObject);
var
   i:integer;
   NewNode:TTreeNode;
begin
   for i := 0 to 10 do begin
       SL.Add(IntTostr(i));
       NewNode := TreeView1.Items.Add(nil,IntToStr(i));
       NewNode.Data := Pointer(SL[i]);
   end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
   SL := TStringList.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
   SL.Free;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
    TreeView1.Parent := Panel1;
end;

編集 削除
LupinⅢ  URL  2004-08-16 14:35:33  No: 10423  IP: 192.*.*.*

実行手順を書き忘れました。

1.ボタン1を押すとツリーノードが作成されます。
2.次にツリーをクリックしてDataプロパティの中身を確認します。
3.ボタン2を押してParentをパネルに変更します
4.ツリーをクリックしてDataプロパティの中身を確認します

編集 削除
質問者  2004-08-16 14:46:49  No: 10424  IP: 192.*.*.*

試してみます

編集 削除
質問者  2004-08-16 14:57:03  No: 10425  IP: 192.*.*.*

すみません
元質問と異なりますがデータが構造体の場合はどうすれば良いでしょうか?

編集 削除
にしの  2004-08-16 14:57:05  No: 10426  IP: 192.*.*.*

こうしても再現できないですね。
LuppinIIIさんのコードを少し変えただけです。
PStringの値、ということでしたので。さらに、親フォームということなので、コントロールでなくTForm2を用意。

でも、言わんとしたいことは何となくわかります。
Stringはプリミティブでないので、PCHARにしたほうがよいです。

  private
    { Private 宣言 }
    s: array[0..10] of string;


procedure TForm1.TreeView1Click(Sender: TObject);
begin
  ShowMessage(PString(TreeView1.Selected.Data)^);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
   i:integer;
   NewNode:TTreeNode;
begin
   for i := 0 to 10 do begin
       s[i] := IntTostr(i);
       NewNode := TreeView1.Items.Add(nil,s[i]);
       NewNode.Data := @s[i];
   end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
    TreeView1.Parent := Form2;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
   Form2.Show;
end;

編集 削除
にしの  2004-08-16 14:58:32  No: 10427  IP: 192.*.*.*

構造体でも同じです。
ただし、構造体の中にオブジェクトを入れるのはよろしくないかもしれません。
TTest=record
  a: string;
  b: string;
  c: string;
end;

でしたら、
TTest=record
  a: PCHAR;
  b: PCHAR;
  c: PCHAR;
end;
として、それぞれバッファを確保して入れましょう。

編集 削除
質問者  2004-08-16 14:59:35  No: 10428  IP: 192.*.*.*

>s: array[0..10] of string;
は動的配列でも良いですか?

編集 削除
質問者  2004-08-16 15:00:30  No: 10429  IP: 192.*.*.*

とりあえず試してみます

編集 削除
LupinⅢ  URL  2004-08-16 15:01:50  No: 10430  IP: 192.*.*.*

私は構造体配列のインデックスをPointer(i)のようにしてDataプロパティに入れています。

編集 削除
質問者  2004-08-16 17:27:36  No: 10431  IP: 192.*.*.*

TTreeNode継承のクラスを作ったほうが良いですか?

編集 削除
LupinⅢ  URL  2004-08-16 17:36:02  No: 10432  IP: 192.*.*.*

作らなくても実現出来るので私は作っていません。

編集 削除
jok  2004-08-16 18:08:21  No: 10433  IP: 192.*.*.*

訳が分からなくなってきましたので、ちょっと確認。

>ツリービューの親フォームを変更するとノードのデータがおかしくなるのですが何故でしょうか?

これは再現しないのでOKですよね? > 質問者さん

動的配列なら、LupinⅢさんのようにインデックスをポインタにキャストする、に一票。
レコード型のフィールドでは string でもOKだと思います。

編集 削除
jok  2004-08-16 18:10:52  No: 10434  IP: 192.*.*.*

蛇足ですが、わたしだったら実行中にコンポーネントの Parent を変えるような
ことはしたくありません。

編集 削除
質問者  2004-08-16 18:29:27  No: 10435  IP: 192.*.*.*

配列で解決しました

編集 削除