Как добавить объекты в виртуальное дерево

Короче говоря, я пытаюсь добавить объект в VirtualTreeView, но всегда получаю ошибку EAccessViolation в CellText я задаюсь вопросом о причине ошибки, которую я пытался сделать все возможное, но безрезультатно...

это моя попытка:

 TForm1 = class(TForm)
 private

 public

 end;

 TPerson = class;

 PPersonNode = ^TPersonNode;
 TPersonNode = record
   PersonObj: TPerson;
 end;

 TPerson = class(TObject)
 private
   FName: string;
 public
   property Name: string read FName write FName;
 end;

 procedure TForm1.Button1Click(Sender: TObject);  
 var
   PersonRec: PPersonNode;
 begin
   PersonRec := VirtualStringTree1.GetNodeData(VirtualStringTree1.AddChild(nil));
   PersonRec.PersonObj := TPerson.Create;
   PersonRec.PersonObj.Name := 'aaa'; 
 end;

 procedure TForm1.VirtualStringTree1GetNodeDataSize(Sender: TBaseVirtualTree;
   var NodeDataSize: Integer);
 begin
   NodeDataSize := SizeOf(TPersonNode);
end;

procedure TForm1.VirtualStringTree1GetText(Sender: TBaseVirtualTree;
  Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
var CellText: string);
var
   PersonRec: PPersonNode;
begin
   PersonRec := Sender.GetNodeData(Node);
   CellText := PersonRec.PersonObj.Name;
end;

2 ответа

Решение

Похоже, событие OnGetText вызывается до того, как объект TPerson был создан. Попробуйте проверить, что объект не ноль сначала:

procedure TForm1.VirtualStringTree1GetText(Sender: TBaseVirtualTree;
  Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
var CellText: string);
var
   PersonRec: PPersonNode;
begin
   PersonRec := Sender.GetNodeData(Node);

   if PersonRec <> nil then  // <- check that the object has been created
     CellText := PersonRec.PersonObj.Name;
end;

Я бы изменил это:

procedure TForm1.Button1Click(Sender: TObject);  
var
 PersonRec: PPersonNode;
begin
 PersonRec := VirtualStringTree1.GetNodeData(VirtualStringTree1.AddChild(VirtualStringTree1.RootNode));
 PersonRec.PersonObj := TPerson.Create;
 PersonRec.PersonObj.Name := 'aaa'; 
end;

и это:

procedure TForm1.VirtualStringTree1GetText(Sender: TBaseVirtualTree;
Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
var CellText: string);
var
 PersonRec: PPersonNode;
begin
 if Assigned(Node) then
 begin
  PersonRec := Sender.GetNodeData(Node);
  CellText := PersonRec.PersonObj.Name;
 end;
end;
Другие вопросы по тегам