【发布时间】:2016-09-07 20:52:50
【问题描述】:
我正在创建带有复选框的 Treeview。我想出了如何将复选框切换到节点(procedure ToggleTreeViewCheckBoxes)。我添加了带有复选框位图的TImageList 组件,并在OnClick treeview 事件中更改了StateIndex。它工作正常,但我想为此添加其他行为。
我以创建树视图结构为例:
-
根 1
-
父 1(复选框)
- 孩子 1(复选框)
- 孩子 2(复选框)
-
父 2(复选框)
- 孩子 1(复选框)
- 孩子 2(复选框)
-
-
根 2
-
父 1(复选框)
- 孩子 1(复选框)
- 孩子 2(复选框)
-
父 2(复选框)
- 孩子 1(复选框)
- 孩子 2(复选框)
-
下面我附上我为创建树视图和添加节点、复选框而准备的示例代码。
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 的更好方法吗?我的意思是不要每次都使用 line ChildNode.StateIndex := 1;
【问题讨论】:
-
标准 Win32 TreeView 控件本机支持复选框(请参阅
TVS_CHECKBOXESwindow style),但TTreeViewVCL 组件至今仍不支持该功能(RSP-15270 )。 -
确实是这样,但是我发现了:"你可以通过覆盖TTreeView的CreateParams过程,为控件指定TVS_CHECKBOXES样式,给treeview添加复选框。结果是所有节点在树视图中将附加复选框。此外,不能再使用 StateImages 属性,因为 WC_TREEVIEW 在内部使用此图像列表来实现复选框“。我不会在每个节点中添加复选框。