gpt4 book ai didi

delphi - 带有复选框的 TreeView - 添加复选框行为

转载 作者:行者123 更新时间:2023-12-03 15:21:59 27 4
gpt4 key购买 nike

我正在努力创建带有复选框的 TreeView 。我弄清楚了如何将复选框切换到节点(procedure ToggleTreeViewCheckBoxes)。我添加了带有复选框位图的 TImageList 组件,并在 OnClick TreeView 事件中更改了 StateIndex 。它工作得很好,但我想添加额外的行为。

我创建了 TreeView 结构作为示例:

  • 根1

    • 父级 1(复选框)

      • 子级 1(复选框)
      • 子级 2(复选框)
    • 父级 2(复选框)

      • 子级 1(复选框)
      • 子级 2(复选框)
  • 根 2

    • 父级 1(复选框)

      • 子级 1(复选框)
      • 子级 2(复选框)
    • 父级 2(复选框)

      • 子级 1(复选框)
      • 子级 2(复选框)

下面我附上我准备的示例代码,用于创建 TreeView 并添加节点、复选框。

unit TreeViewCheckboxes;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, System.ImageList, Vcl.ImgList,
Vcl.ComCtrls;

type
TForm5 = class(TForm)
ImageList1: TImageList;
TreeView1: TTreeView;
procedure FormCreate(Sender: TObject);
procedure TreeView1Click(Sender: TObject);
private
{ Private declarations }
procedure ToggleTreeViewCheckBoxes(Node:TTreeNode; cUnChecked, cChecked: Integer);
public
{ Public declarations }
end;

var
Form5: TForm5;

const
cStateUnCheck = 1;
cStateChecked = 2;

aRootList: Array[1..2] of String =
(
'Root 1',
'Root 2'
);

implementation

{$R *.dfm}

{ TForm5 }

procedure TForm5.FormCreate(Sender: TObject);
var
RootNode: TTreeNode;
ParentNode: TTreeNode;
ChildNode: TTreeNode;
i: Integer;
begin
for i := 1 to High(aRootList) do
begin
RootNode := TreeView1.Items.Add(nil, aRootList[i]);

ParentNode := TreeView1.Items.AddChild(RootNode, 'Parent 1');
ParentNode.StateIndex := 1;
ChildNode := TreeView1.Items.AddChild(ParentNode, 'Child 1');
ChildNode.StateIndex := 1;
ChildNode := TreeView1.Items.AddChild(ParentNode, 'Child 2');
ChildNode.StateIndex := 1;

ParentNode := TreeView1.Items.AddChild(RootNode, 'Parent 2');
ParentNode.StateIndex := 1;
ChildNode := TreeView1.Items.AddChild(ParentNode, 'Child 1');
ChildNode.StateIndex := 1;
ChildNode := TreeView1.Items.AddChild(ParentNode, 'Child 2');
ChildNode.StateIndex := 1;
end;
end;

procedure TForm5.ToggleTreeViewCheckBoxes(Node: TTreeNode; cUnChecked,
cChecked: Integer);
begin
if Assigned(Node) then
begin
if Node.StateIndex = cUnChecked then
Node.StateIndex := cChecked
else if Node.StateIndex = cChecked then
Node.StateIndex := cUnChecked;
end;
end;

procedure TForm5.TreeView1Click(Sender: TObject);
var
P: TPoint;
begin
GetCursorPos(P);
P := TreeView1.ScreenToClient(P);
if (htOnStateIcon in TreeView1.GetHitTestInfoAt(P.X, P.Y)) then
ToggleTreeViewCheckBoxes(TreeView1.Selected, cStateUnCheck, cStateChecked);
end;
end.

问题:

1)我怎样才能做这样的事情:如果我点击任何Parent复选框节点,所有子节点都被取消选中?

2)您知道有什么更好的方法来动态添加节点并为所有子节点设置StateIndex吗?我的意思是不是每次都使用行 ChildNode.StateIndex := 1;

最佳答案

1) How can I do something like that: If I click on any Parent checkbox node, all child nodes are unchecked?

您必须手动迭代所有子项,例如:

procedure TForm5.SetTreeViewCheckState(Node: TTreeNode; StateIndex: Integer; Recursive: Boolean);
begin
Node.StateIndex := StateIndex;
if not Recursive then Exit;
for I := 0 to Node.Count-1 do
SetTreeViewCheckState(Node.Item[I], StateIndex, True);
end;

procedure TForm5.ToggleTreeViewCheckBoxes(Node: TTreeNode);
var
I: Integer;
begin
if Assigned(Node) then
begin
if Node.StateIndex = cStateUnCheck then
SetTreeViewCheckState(Node, cStateChecked, False);
else if Node.StateIndex = cStateChecked then
SetTreeViewCheckState(Node, cStateUnCheck, True);
end;
end;

2) Do you know any better way to dynamically add nodes and set StateIndex for all childs? I mean no every time use line ChildNode.StateIndex := 1;

抱歉,但这是唯一的方法。但你可以将它包装在一个函数中:

procedure TForm5.FormCreate(Sender: TObject);
var
RootNode: TTreeNode;
ParentNode: TTreeNode;
i: Integer;
begin
for i := Low(aRootList) to High(aRootList) do
begin
RootNode := TreeView1.Items.Add(nil, aRootList[i]);

ParentNode := AddChildNodeWithState(RootNode, 'Parent 1');
AddChildNodeWithState(ParentNode, 'Child 1');
AddChildNodeWithState(ParentNode, 'Child 2');

ParentNode := AddChildNodeWithState(RootNode, 'Parent 2');
AddChildNodeWithState(ParentNode, 'Child 1');
AddChildNodeWithState(ParentNode, 'Child 2');
end;
end;

function TForm5.AddChildNodeWithState(AParentNode: TTreeNode, const ACaption: String; AStateIndex: Integer = 1): TTreeNode;
begin
Result := TreeView1.Items.AddChild(AParentNode, ACaption);
Result.StateIndex := AStateIndex;
end;

或者,您可以创建 class helper (您也可以将其用于切换逻辑):

type
TTreeNodeHelper = class helper for TTreeNode
public
function AddChildWithState(const ACaption: string; AStateIndex: Integer = 1): TTreeNode;
procedure SetCheckState(StateIndex: Integer; Recursive: Boolean);
procedure ToggleCheckState;
end;

function TTreeNodeHelper.AddChildWithState(const ACaption: string; AStateIndex: Integer = 1): TTreeNode;
begin
Result := Self.TreeView.Items.AddChild(Self, ACaption);
Result.StateIndex := AStateIndex;
end;

procedure TTreeNodeHelper.SetCheckState(StateIndex: Integer; Recursive: Boolean);
begin
Self.StateIndex := StateIndex;
if not Recursive then Exit;
for I := 0 to Self.Count-1 do
Self.Item[I].SetCheckState(StateIndex, True);
end;

procedure TTreeNodeHelper.ToggleCheckState;
var
I: Integer;
begin
if Self.StateIndex = cStateUnCheck then
SetCheckState(cStateChecked, False);
else if Self.StateIndex = cStateChecked then
SetCheckState(cStateUnCheck, True);
end;
end;

procedure TForm5.FormCreate(Sender: TObject);
var
RootNode: TTreeNode;
ParentNode: TTreeNode;
i: Integer;
begin
for i := Low(aRootList) to High(aRootList) do
begin
RootNode := TreeView1.Items.Add(nil, aRootList[i]);

ParentNode := RootNode.AddChildWithState('Parent 1');
ParentNode.AddChildWithState('Child 1');
ParentNode.AddChildWithState('Child 2');

ParentNode := RootNode.AddChildWithState('Parent 2');
ParentNode.AddChildWithState('Child 1');
ParentNode.AddChildWithState('Child 2');
end;
end;

procedure TForm5.TreeView1Click(Sender: TObject);
var
P: TPoint;
begin
GetCursorPos(P);
P := TreeView1.ScreenToClient(P);
if (htOnStateIcon in TreeView1.GetHitTestInfoAt(P.X, P.Y)) then
TreeView1.GetNodeAt(P.X, P.Y).ToggleCheckState;
end;

如果您使用的是不支持类助手的旧版 Delphi,您可以从 TTreeNode 派生一个类,并将其与 TreeView 的 OnCreateNodeClass 一起使用。事件,例如:

type
TMyTreeNode = class(TTreeNode)
public
function AddChildWithState(const ACaption: string; AStateIndex: Integer = 1): TTreeNode;
procedure SetCheckState(StateIndex: Integer; Recursive: Boolean);
procedure ToggleCheckState;
end;

function TMyTreeNode.AddChildWithState(const ACaption: string; AStateIndex: Integer = 1): TTreeNode;
begin
Result := Self.TreeView.Items.AddChild(Self, ACaption);
Result.StateIndex := AStateIndex;
end;

procedure TMyTreeNode.SetCheckState(StateIndex: Integer; Recursive: Boolean);
begin
Self.StateIndex := StateIndex;
if not Recursive then Exit;
for I := 0 to Self.Count-1 do
TMyTreeNode(Self.Item[I]).SetCheckState(StateIndex, True);
end;

procedure TMyTreeNode.ToggleCheckBoxes;
var
I: Integer;
begin
if Self.StateIndex = cStateUnCheck then
SetCheckBoxes(cStateChecked, cStateUnChecked);
else if Self.StateIndex = cStateChecked then
SetCheckBoxes(cStateUnCheck, cStateUnChecked);
end;
end;

procedure TForm5.FormCreate(Sender: TObject);
var
RootNode: TTreeNode;
ParentNode: TTreeNode;
i: Integer;
begin
for i := Low(aRootList) to High(aRootList) do
begin
RootNode := TreeView1.Items.Add(nil, aRootList[i]);

ParentNode := TMyTreeNode(RootNode).AddChildWithState('Parent 1');
TMyTreeNode(ParentNode).AddChildWithState('Child 1');
TMyTreeNode(ParentNode).AddChildWithState('Child 2');

ParentNode := TMyTreeNode(RootNode).AddChildWithState('Parent 2');
TMyTreeNode(ParentNode).AddChildWithState('Child 1');
TMyTreeNode(ParentNode).AddChildWithState('Child 2');
end;
end;

procedure TForm5.TreeView1Click(Sender: TObject);
var
P: TPoint;
begin
GetCursorPos(P);
P := TreeView1.ScreenToClient(P);
if (htOnStateIcon in TreeView1.GetHitTestInfoAt(P.X, P.Y)) then
TMyTreeNode(TreeView1.GetNodeAt(P.X, P.Y)).ToggleCheckState;
end;

procedure TForm5.TreeView1CreateNodeClass(Sender: TCustomTreeView; var NodeClass: TTreeNodeClass)
begin
NodeClass := TMyTreeNode;
end;

关于delphi - 带有复选框的 TreeView - 添加复选框行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39378814/

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