加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – VirtualStringTree – 使用对象时添加/处理子节点/子

发布时间:2020-12-15 09:33:31 所属栏目:大数据 来源:网络整理
导读:我正在使用Delphi2010并尝试使用VirtualStringTree. 我一直试图让它与对象一起工作,并且在我遵循Philipp Frenzel的Virtual TreeView教程之前没有运气,我在soft-gems.net网站上找到了该教程.到目前为止我提出的工作原理,但我认为我没有正确处理子节点(即子节
我正在使用Delphi2010并尝试使用VirtualStringTree.

我一直试图让它与对象一起工作,并且在我遵循Philipp Frenzel的Virtual TreeView教程之前没有运气,我在soft-gems.net网站上找到了该教程.到目前为止我提出的工作原理,但我认为我没有正确处理子节点(即子节点).

我唯一能够工作的就是为每个孩子再次链接整个对象,然后只显示我需要的字段 – 但它只是感觉错了.

建议/反馈非常感谢.

我有一些对象列表,我正在尝试与VirtualStringTree连接,我正在尝试实现这样的事情,其中??一个字段将作为父项的标签,其余字段显示为子节点.

>罗伯特莱恩

>男
> 35
>洛杉矶
>布鲁内特

>简·多伊

>女
> 19
>丹佛
>红头发

这就是我班级的设置方式.

type
  PTreeData = ^TTreeData;
  TTreeData = record
    FObject : TObject;
  end;

  TCustomerNode = class(TObject)
  private
    fName: string;
    fSex: string;
    fAge: integer;
    fHair: string;
    //...
  public
    property Name: string read fName write fName;
    //...
  end;

一旦我填充了对象,我就将它们添加到另一个基于TList的类(CustomerObjectList),如下所述.

这是我将VirtualStringTree与我的对象列表连接的地方

procedure TfrmMain.btnLoadDataClick(Sender: TObject);
var
  i,j : integer;
  CustomerDataObject: TCustomerNode;
  RootXNode,XNode: PVirtualNode;
  Data: PTreeData;
begin
  vstree.NodeDataSize := SizeOf( TTreeData );

  vstree.BeginUpdate;
  for i := 0 to CustomerObjectList.Count - 1 do
  begin
    CustomerDataObject := CustomerObjectList[i];

    //load data for parent node
    RootXNode := vstree.AddChild(nil);
    Data  := vstree.GetNodeData(RootXNode);
    Data^.FObject:= PINodeSource;

    //now add children for rest of fields
    //Isn't there a better way to do this?
    for j := 1 to NUMBERofFIELDS -1 do  //first field is label for parent so -1
    begin
      XNode := vstree.AddChild(RootXNode);
      Data  := vstree.GetNodeData(XNode);
      Data^.FObject:= PINodeSource;
    end;

  end;
  vstree.EndUpdate; 
end;    

procedure TfrmMain.vstreeGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
 Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
var
  Data : PTreeData;
begin
  Data := vstObjects.GetNodeData(Node);
  ////if Node.ChildCount  = 0 then //edit - oops typo!
  if Node.ChildCount  > 0 then
  begin
    CellText := TCustomerNode(Data.FObject).Name;
    exit;
  end;

  //handle childnodes
  case Node.Index of
    0:  CellText := TCustomerNode(Data.FObject).Sex;
    1:  CellText := IntToStr(TCustomerNode(Data.FObject).Age);
    2:  CellText := TCustomerNode(Data.FObject).Hair;
    3:  CellText := TCustomerNode(Data.FObject).City;
  end;  
end;

解决方法

您无需将所有数据加载到树中.您可以使用树的“虚拟性”.我就是这样做的.

将树的RootNodeCount设置为CustomerObjectList中的记录数:

vstree.RootNodeCount := CustomerObjectList.Count;

然后,在OnInitChildren事件中,将0级节点的子计数设置为要显示的属性数:

procedure TfrmMain.vstreeInitNode(Sender: TBaseVirtualTree; ParentNode,Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
begin
  if Sender.GetNodeLevel(Node) = 0 then
  begin
    Sender.ChildCount[Node] := 4;

    // Comment this out if you don't want the nodes to be initially expanded
    Sender.Expanded[Node] := TRUE;
  end;
end;

现在,只需在OnGetText事件中检索正确的数据.

procedure TfrmMain.vstreeGetText(Sender: TBaseVirtualTree;
  Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
  var CellText: string);
begin
  if Column <= 0 then
  begin
    if Sender.GetNodeLevel(Node) = 0 then
      CellText := CustomerObjectList[Node.Index].Name else
    if Sender.GetNodeLevel(Node) = 1 then
    begin
      case Node.Index of
        0: CellText := CustomerObjectList[Parent.Node.Index].Sex;
        1: CellText := CustomerObjectList[Parent.Node.Index].Age;
        2: CellText := CustomerObjectList[Parent.Node.Index].Hair;
        3: CellText := CustomerObjectList[Parent.Node.Index].City;
      end; // of case
     end;
end;

您可能希望添加更多范围检查,以防万一.

希望这可以帮助.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读