Pergunta

In short, I'm trying to add Object into VirtualTreeView but am always getting error EAccessViolation at CellText I'm wondering about the reason for the error i tried to do my best but without result...

this is my attempt:

 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;
Foi útil?

Solução

It looks like the OnGetText event is being fired before the TPerson object has been created. Try checking that the object isn't nil first:

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;

Outras dicas

I would change this:

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;

and this:

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;
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top