我有一个现有的TreeView,其中节点是使用创建的
jQuery( document ).ready(function() {
jQuery('.widget > ul').addClass('nav nav-list');
});
(即没有添加数据对象)
我想在每个节点上添加一条记录,以便为每个节点存储一些数据。
有没有办法解决这个问题?
答案 0 :(得分:4)
定义您自己的类型。这是基于Delphi7帮助。
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()分配的内存,尽管在程序退出时释放了这个内存。这可以在TreeView的OnDeletion事件中完成:
procedure TForm1.treeDeletion(Sender: TObject; Node: TTreeNode);
begin
Dispose(PItemRecord(Node.Data));
end;
答案 1 :(得分:0)
虽然Zhorov的回答很好,但如果使用不当可能会导致内存泄漏。
也就是说,如果您使用New
分配记录,则必须确保在删除树节点之前释放记录。
我不会使用记录,而是将自定义类的对象分配给节点的Data属性,并使用TObjectList
跟踪对象,以确保在表单(或者申请)已关闭。
以下是Zhorov代码的修改版本:
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. ...
当然,使用对象而不是记录会占用更多内存,如果有数千个节点,则可能会影响性能。