gpt4 book ai didi

delphi - VirtualTreeview 节点,将它们传递给另一种形式?

转载 作者:行者123 更新时间:2023-12-03 18:54:34 25 4
gpt4 key购买 nike

我的应用程序将通过虚拟节点循环并检查它们的数据。我正在使用另一种表单来执行此操作,而不是包含 VirtualStringTree 的表单。 (我有我的理由;))

我的问题是:如何将这些节点+它们的数据传递给我其他形式的函数,然后该函数将能够通过节点循环(我知道如何循环,我只需要节点以我的其他形式可用)。

另外,请注意,一旦显示处理表单,包含 VirtualStringTree 的表单就会被销毁!

我怎么能那样做?我正在考虑创建一个动态的 VirtualStringTree,并以某种方式将节点从一棵树传递到另一棵树,但我会先在这里询问任何更好的解决方案。 :)

谢谢,杰夫。

最佳答案

I've mentioned before你做错了,现在你会明白为什么。

您正在使用树控件来存储数据。它用于显示数据。您应该有一个单独的数据结构,其唯一的工作就是存储您的数据。它可能是 tree ,但不是树控件。这是您提供给处理表单的树数据结构,因为它不需要显示节点。

当你想显示你的数据时,你要知道你的树的第一层有多少个节点,然后你设置你的树控件的RootNodeCount该号码的属性(property)。控件将分配那么多节点——不要调用 AddNewNode用于填充控件等批量操作。当树要在屏幕上显示一个之前没有显示的节点时,它会触发 OnInitNode事件处理程序。这是您初始化节点并将其与数据结构中的值相关联的地方。树控件会告诉你它正在初始化哪个节点——都通过 PVirtualNode指针并通过一个索引告诉它是哪个节点,相对于它的父节点。当你初始化节点时,你告诉树节点是否有任何子节点。你不需要告诉它有多少个 child ;如果控件想知道,它会问你另一个事件。

既然您已经将数据与数据的单纯呈现分开,您就不必再担心呈现者的生命周期与数据的生命周期不同。处理表单可以处理数据而无需考虑 TreeView 控件是否仍然存在,因为 TreeView 控件从一开始就没有拥有数据。

也可以看看:

  • Model–View–Controller


  • 你说过你只有一级节点。没关系。只有一层的树通常称为列表。您可以使用多种方法来跟踪列表。最简单的是数组。您也可以使用 TList ,或者您可以构建自己的链表。这个例子将使用一个数组,因为我想专注于树控件。

    假设每个节点的数据由一条记录表示, TData ,所以你有一个数组:
    var
    Data: array of TData;

    在您为数组加载信息后,无论您拥有什么来源,您都可以准备填充树控件了。这就像两行代码一样简单(一行,如果控件开始为空):
    Tree.ResetNode(nil); // remove all existing nodes from tree
    Tree.RootNodeCount := Length(Data); // allocate new nodes for all data

    当树确定它需要有关任何这些节点的更多信息时,它将首先触发 OnInitNode事件。由于节点的 Index,您无需为该事件执行任何操作。字段足以让我们找到 TData对应于任何给定树节点的记录。
    procedure TJeffForm.TreeInitNode(Sender: TBaseVirtualTree;
    ParentNode, Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
    begin
    Assert(Node.Index < Length(Data), 'More nodes than data elements!?');
    InitialStates := []; // If the node had children, or if it should be
    // initially disabled, you'd set that here.
    end;

    当树想要绘制自己时,它会通过触发 OnGetText 来询问您为每个可见节点显示什么文本。事件。 Index节点的字段告诉你它是哪个项目,相对于它的父节点。 (由于您只有一个列表,因此该索引对应于列表中的索引。)
    procedure TJeffForm.TreeGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
    Column: TColumnIndex; TextType: TVSTTextType; var CellText: UnicodeString);
    begin
    if TextType = ttStatic then
    exit;
    case Column of
    NoColumn,
    0: CellText := Data[Node.Index].Name;
    1: CellText := 'Second column';
    else
    Assert(False, 'Requested text for unexpected column');
    end;
    end;

    以上我假设 TData有一个名为 Name 的字符串字段这就是我们应该在主列中显示的内容。如果树要求第二列之后的任何文本,我们将得到一个断言失败,表明我们还没有准备好发布产品。

    请注意我们如何使用节点索引来查看完全独立的数组数据结构。我们可以完全销毁树控件,数据仍然存在。当您的处理表单需要处理数据时,给它 Data数组,而不是树控件。

    关于delphi - VirtualTreeview 节点,将它们传递给另一种形式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4902471/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com