3

我在显示某些文件描述的表单上有一个 cxTreeView。我希望能够选择单击描述之一并返回文件名。为了做到这一点,我需要在树视图中存储一些额外的数据,这就是我的问题。

我该怎么做:存储文件名和描述,只显示描述但通过双击获取文件名?

4

3 回答 3

2

如果没有紧急需要使用 TcxTreeView,我认为您可以使用 TcxTreeList 来完成此任务(如果可能)。在 TcxTreeList 中,您可以添加一个新列并将文件名存储在其中。然后使该列不可见。

如果您必须依赖 TcxTreeView,则无法在 TTreeNodes 中直接存储数据(如字符串)。您可以将指向任何对象的指针存储到 TTreeNode 的属性“数据”中。

于 2012-06-23T10:53:55.600 回答
1

在这两个答案中都提到了TcxTreeView使用标准TTreeNode,正如沃伦his answer首先指出的那样,您可以使用该TTreeNode.Data属性来存储您的数据。我将通过一个例子来完成这些想法。

更新:

这篇文章的先前版本仅适用于自动为其分配空间的常量字符串。如果您需要将变量传递给TTreeNode.Data您必须自己分配和释放内存。这是使用简单辅助函数的示例。

AddFileNode辅助函数将节点添加到Items具有ParentNode名称的 中,FileDesc并分配空间并使用该函数复制传递FileName给 的。TTreeNode.DataStrNew

当您需要修改数据时,您应该释放(或者更好,但有点复杂的是重新分配)分配的内存并分配空间并复制新值。为此,您可以使用ChangeFileNamewhich 处理之前分配的字符串内存并分配空间并复制传递的FileName值。

正如我之前提到的,您需要自己处理内存处理,为此,OnDeletion事件是最好的地方。因此,为此事件编写处理程序,您将在其中释放添加项目时分配的内存。

function AddFileNode(Items: TTreeNodes; ParentNode: TTreeNode;
  const FileName, FileDesc: string): TTreeNode;
begin
  Result := Items.AddChildObject(ParentNode, FileDesc, StrNew(PChar(FileName)));
end;

function ChangeFileName(TreeNode: TTreeNode; const FileName: string): Boolean;
begin
  Result := False;
  if Assigned(TreeNode.Data) then
  begin
    Result := True;
    StrDispose(PChar(TreeNode.Data));
    TreeNode.Data := StrNew(PChar(FileName));
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  S: string;
begin
  S := 'C:\FileName 1.xxx';
  AddFileNode(cxTreeView1.Items, nil, S, 'File 1');
  S := 'C:\FileName 2.xxx';
  AddFileNode(cxTreeView1.Items, nil, S, 'File 2');
end;

procedure TForm1.cxTreeView1Deletion(Sender: TObject; Node: TTreeNode);
begin
  if Assigned(Node.Data) then
    StrDispose(PChar(Node.Data));
end;

procedure TForm1.cxTreeView1DblClick(Sender: TObject);
var
  CurrentPos: TPoint;
  CurrentNode: TTreeNode;
begin
  CurrentPos := cxTreeView1.ScreenToClient(Mouse.CursorPos);
  if (htOnItem in cxTreeView1.GetHitTestInfoAt(CurrentPos.X, CurrentPos.Y)) then
  begin
    CurrentNode := cxTreeView1.GetNodeAt(CurrentPos.X, CurrentPos.Y);
    if Assigned(CurrentNode) and Assigned(CurrentNode.Data) then
      ShowMessage(PChar(CurrentNode.Data));
  end;
end;
于 2012-06-25T02:25:58.993 回答
0

如果节点是常规的 TTreeNode,则可以使用 Node 对象中的 Data:Pointer 值。

如果树中的节点是 type TcxTreeListNode,它们包含存储您想要的任何数据值的能力。当我查看源代码时,我在节点级别看到了这些属性:

property ValueCount: Integer read GetValueCount;
property Values[Index: Integer]: Variant read GetValue write SetValue;
于 2012-06-23T11:08:02.220 回答