1

私のアプリケーションは、仮想ノードを介してループし、それらのデータをチェックします。これを行うために、VirtualStringTree を含むフォームとは別のフォームを使用しています。(理由はわかりました;))

私の質問は次のとおりです。これらのノードとそのデータを他のフォームの関数に渡すにはどうすればよいですか。これにより、ノードをループできるようになります (ループの方法は知っています。他のフォームでノードを使用できるようにする必要があるだけです)。 )。

また、Processing フォームが表示されると、VirtualStringTree を含むフォームが破棄されることに注意してください。

どうすればそれができますか?動的な VirtualStringTree を作成し、何らかの方法でノードをあるツリーから別のツリーに渡すことを考えていますが、最初にここでより良い解決策を求めます。:)

ありがとう、ジェフ。

4

1 に答える 1

13

前に、あなたが間違ったことをしていると言いましたが、今ならその理由がわかります。

ツリー コントロールを使用してデータを保存しています。データを表示するためのものです。唯一の仕事がデータを保存することである別のデータ構造が必要です。おそらくツリーになりますが、ツリーコントロールではありません。ノードを表示する必要がないため、処理フォームに渡すのはこのツリー データ構造です。

データを表示するには、ツリーの最初のレベルにあるノードの数を調べ、ツリー コントロールのRootNodeCountプロパティをその数に設定します。AddNewNodeコントロールはその数のノードを割り当てます — コントロールへの入力などの一括操作を呼び出さないでください。ツリーが以前に表示されていないノードを画面に表示しようとすると、OnInitNodeイベント ハンドラーが起動されます。ここでノードを初期化し、データ構造の値に関連付けます。ツリー コントロールは、どのノードが初期化されているかを示します —PVirtualNodeポインタと、その親に対してどのノードであるかを示すインデックスの両方を介して。ノードを初期化するときに、ノードに子があるかどうかをツリーに伝えます。人かは言う必要ない子供はまだ; コントロールが知りたい場合は、別のイベントで尋ねます。

データを単なるプレゼンテーションから切り離したので、プレゼンターの存続期間がデータの存続期間と異なることを心配する必要がなくなりました。処理フォームは、ツリー ビュー コントロールが最初からデータを所有していないため、ツリー ビュー コントロールがまだ存在するかどうかに関係なくデータを処理できます。

以下も参照してください。


ノードのレベルは 1 つだけだとおっしゃいました。それで大丈夫です。レベルが 1 つしかないツリーは、より一般的にはリストとして知られています。リストを追跡するために使用できるものがいくつかあります。最も単純なのは配列です。を使用することもTList、独自のリンク リストを作成することもできます。ツリー コントロールに注目したいので、この例では配列を使用します。

各ノードのデータがレコードで表されていると仮定すると、TDataこれらの配列が得られます。

var
  Data: array of TData;

配列に情報をロードしたら、ソースに関係なく、ツリー コントロールにデータを入力する準備が整います。これは 2 行のコード (コントロールが空の状態で開始した場合は 1 行) と同じくらい簡単です。

Tree.ResetNode(nil); // remove all existing nodes from tree
Tree.RootNodeCount := Length(Data); // allocate new nodes for all data

ツリーは、それらのノードのいずれかに関する詳細情報が必要であると判断すると、OnInitNodeイベントをトリガーすることから始めます。ノードのフィールドは、特定のツリー ノードに対応するレコードIndexを見つけるのに十分であるため、そのイベントに対して行う必要があることはあまりありません。TData

procedure TJeffForm.TreeInitNode(Sender: TBaseVirtualTree;
    ParentNode, Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
begin
  Assert(Node.Index < Length(Data), 'More nodes than data elements!?');
  InitialStates := []; // If the node had children, or if it should be
                       // initially disabled, you'd set that here.
end;

OnGetTextツリーがそれ自体をペイントする場合、イベントをトリガーして、表示されているノードごとに表示するテキストを尋ねます。ノードのIndexフィールドは、その親に対してどのアイテムであるかを示します。(リストがあるだけなので、そのインデックスはリスト内のインデックスに対応します。)

procedure TJeffForm.TreeGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
    Column: TColumnIndex; TextType: TVSTTextType; var CellText: UnicodeString);
begin
  if TextType = ttStatic then
    exit;
  case Column of
    NoColumn,
    0: CellText := Data[Node.Index].Name;
    1: CellText := 'Second column';
    else
      Assert(False, 'Requested text for unexpected column');
  end;
end;

TData上記では、 という名前の文字列フィールドがNameあり、それがメイン列に表示されるものであると想定しました。ツリーが 2 列目以降のテキストを要求すると、アサーション エラーが発生し、まだ製品をリリースする準備ができていないことが示されます。

ノード インデックスを使用して、完全に別個の配列データ構造を調べる方法に注目してください。ツリー コントロールを完全に破棄しても、データはまだ存在します。処理フォームでデータを処理する必要がある場合Dataは、ツリー コントロールではなく、配列を渡してください。

于 2011-02-04T20:47:21.033 に答える