我在显示某些文件描述的表单上有一个 cxTreeView。我希望能够选择单击描述之一并返回文件名。为了做到这一点,我需要在树视图中存储一些额外的数据,这就是我的问题。
我该怎么做:存储文件名和描述,只显示描述但通过双击获取文件名?
我在显示某些文件描述的表单上有一个 cxTreeView。我希望能够选择单击描述之一并返回文件名。为了做到这一点,我需要在树视图中存储一些额外的数据,这就是我的问题。
我该怎么做:存储文件名和描述,只显示描述但通过双击获取文件名?
如果没有紧急需要使用 TcxTreeView,我认为您可以使用 TcxTreeList 来完成此任务(如果可能)。在 TcxTreeList 中,您可以添加一个新列并将文件名存储在其中。然后使该列不可见。
如果您必须依赖 TcxTreeView,则无法在 TTreeNodes 中直接存储数据(如字符串)。您可以将指向任何对象的指针存储到 TTreeNode 的属性“数据”中。
在这两个答案中都提到了TcxTreeView
使用标准TTreeNode
,正如沃伦his answer
首先指出的那样,您可以使用该TTreeNode.Data
属性来存储您的数据。我将通过一个例子来完成这些想法。
更新:
这篇文章的先前版本仅适用于自动为其分配空间的常量字符串。如果您需要将变量传递给TTreeNode.Data
您必须自己分配和释放内存。这是使用简单辅助函数的示例。
AddFileNode
辅助函数将节点添加到Items
具有ParentNode
名称的 中,FileDesc
并分配空间并使用该函数复制传递FileName
给 的。TTreeNode.Data
StrNew
当您需要修改数据时,您应该释放(或者更好,但有点复杂的是重新分配)分配的内存并分配空间并复制新值。为此,您可以使用ChangeFileName
which 处理之前分配的字符串内存并分配空间并复制传递的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;
如果节点是常规的 TTreeNode,则可以使用 Node 对象中的 Data:Pointer 值。
如果树中的节点是 type TcxTreeListNode
,它们包含存储您想要的任何数据值的能力。当我查看源代码时,我在节点级别看到了这些属性:
property ValueCount: Integer read GetValueCount;
property Values[Index: Integer]: Variant read GetValue write SetValue;