Delphi - Как добавить запись в существующий триод - PullRequest
0 голосов
/ 17 мая 2018

У меня есть существующее TreeView, где узлы были созданы с использованием TreeView1.Items.Add(Nil,'abc'); (т. Е. Объекты данных не добавлены)

Я хотел бы добавить запись в каждый из узлов, чтобы сохранить некоторые данные с каждымУзел.

Есть ли способ к этому ??

Ответы [ 2 ]

0 голосов
/ 17 мая 2018

Хотя ответ Жорова работает просто отлично, он может привести к утечке памяти при неправильном использовании.

То есть, если вы выделяете запись с New, вы должны убедиться, что запись будет освобождена до того, какудаление узла дерева.

Вместо использования записей я бы назначил объекты пользовательского класса свойству Data узла и отслеживал объекты с помощью TObjectList, чтобы сделатьубедитесь, что они правильно уничтожены, когда форма (или приложение) закрыта.

Вот модифицированная версия кода Жорова:

unit FMainTree;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, Contnrs;

type
  TMyItem = class
  private
    FText: string;
  public
    property Text: string read FText write FText;
  end;

  TForm1 = class(TForm)
    tree: TTreeView;
    ButtonAdd: TButton;
    procedure ButtonAddClick(Sender: TObject);
  private
    FItemList: TObjectList;
  public
    procedure AfterConstruction();
    procedure BeforeDestruction();
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure AfterConstruction();
begin
  inherited;
  // `True` = automatically destroy items when deleted from the list or the list is destroyed
  FItemList := TObjectList.Create(True); 
end;

procedure BeforeDestruction();
begin
  // Destroying the list will also destroy the object items inside
  FItemList.Free;
  inherited;
end;

procedure TForm1.ButtonAddClick(Sender: TObject);
var
   i: Integer;
   objData: TMyItem;
   node: TTreeNode;
begin
  // Add nodes without 'Data'
  tree.Items.Add(nil, 'Item1');
  tree.Items.Add(nil, 'Item2');
  tree.Items.Add(nil, 'Item3');

  // Add 'Data'
  for i := 0 to tree.Items.Count-1 do begin
    node := tree.Items[i];

    objData := TMyItem.Create();
    try
      objData.Text := 'Text for node ' + node.Text;
    finally
      FItemList.Add(objData);
    end;

    node.Data := objData;
  end{for};

  // Show 'Data' for second item
  ShowMessage(TMyItem(tree.Items[1].Data).Text);
end;

end.

Я намеренно использовал неуниверсальныйверсия TObjectList (из модуля Contnrs), так как вы не указали версию Delphi, которая у вас есть, поэтому она может не иметь обобщений.Но если у вас Delphi 2009 или новее, обратитесь к следующей статье за ​​примерами того, как использовать это вместо: Generics Collections TObjectList (Delphi) :

...
var
  List: TObjectList<TNewObject>;
  Obj: TNewObject;
begin
  { Create a new List. }
  { The OwnsObjects property is set by default to true -- the list will free the owned objects automatically. }
  List := TObjectList<TNewObject>.Create();

  { Add some items to the List. }
  List.Add(TNewObject.Create('One'));
  List.Add(TNewObject.Create('Two'));

  ...

  List.Free;
end.
...

Конечно, использование объектов вместо записей потребляет больше памяти, и если у вас есть тысячи узлов, это может повлиять на производительность.

0 голосов
/ 17 мая 2018

Определите свои собственные типы. Это основано на Delphi7 Help.

type
  PItemRecord = ^TItemRecord;
  TItemRecord = record
     Text: string;
  end;

Рабочий пример:

unit FMainTree;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls;

type
  PItemRecord = ^TItemRecord;
  TItemRecord = record
     Text: string;
  end;

type
  TForm1 = class(TForm)
    tree: TTreeView;
    ButtonAdd: TButton;
    procedure ButtonAddClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.ButtonAddClick(Sender: TObject);
var
   i: Integer;
   pdata: PItemRecord;
   node: TTreeNode;
begin
   // Add nodes without 'Data'
   tree.Items.Add(nil, 'Item1');
   tree.Items.Add(nil, 'Item2');
   tree.Items.Add(nil, 'Item3');
   // Add 'Data'
   for i := 0 to tree.Items.Count-1 do begin
      node := tree.Items[i];
      New(pdata);
      pdata^.Text := 'Text for node ' + node.Text;
      node.Data := pdata;
   end{for};
   // Show 'Data' for second item
   ShowMessage(PItemRecord(tree.Items[1].Data)^.Text);
end;

end.

Примечания:

Хорошей практикой является уничтожение памяти, выделенной с помощью New (), хотя эта память освобождается при выходе из программы. Это можно сделать в событии OnDeletion TreeView:

procedure TForm1.treeDeletion(Sender: TObject; Node: TTreeNode);
begin
   Dispose(PItemRecord(Node.Data));
end;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...