写用户组管理,需要对树进行操作.主要是勾选状态的一致性比较难处理,在网上搜索了一下没结果,就自己动手写了一个.核心函数主要有三个,供大家参考,如果还有更好的算法,希望大家能交流.
注:我所用的是cxTreeView
//所有子节点是否有处于选中状态
function ChildChecked(TreeNode:TTreeNode):Boolean;
//改变所有子节点状态
procedure ChangeChildState(sParent:TTreeNode;StateIndex:Integer);
//改变父节点状态
procedure ChangeParentState(TreeNode:TTreeNode;StateIndex:Integer);
function TfrmRole.ChildChecked(TreeNode:TTreeNode):Boolean;
var
I : Integer;
begin
Result := False;
for I := 0 to TreeNode.Count - 1 do
begin
if TreeNode[I].HasChildren then
begin
if 2 = TreeNode[I].StateIndex then
begin
Result := True;
Exit;
end;
ChildChecked(TreeNode[I]);
end
else begin
if 2 = TreeNode[I].StateIndex then
begin
Result := True;
Exit;
end;
end;
end;
end;
procedure TfrmRole.ChangeChildState(sParent: TTreeNode; StateIndex: Integer);
var
I : Integer;
begin
sParent.StateIndex := StateIndex;
for I := 0 to sParent.Count - 1 do
begin
if sParent[I].HasChildren then
begin
sParent[I].StateIndex := StateIndex;
ChangeChildState(sParent[I],StateIndex);
end
else
sParent[I].StateIndex := StateIndex;
end;
end;
procedure TfrmRole.ChangeParentState(TreeNode: TTreeNode; StateIndex: Integer);
var
I : Integer;
begin
if TreeNode.Parent = nil then
Exit;
//如果父节点是勾选状态,则要判断是否有其它节点是勾选状态,如果有,则退出,保持勾选
if 2 = TreeNode.Parent.StateIndex then
begin
if ChildChecked(TreeNode.Parent) then
Exit;
end;
TreeNode.Parent.StateIndex := StateIndex;
ChangeParentState(TreeNode.Parent,StateIndex);
end;
这段代码也比较有用,这个是点中节点才改变状态,点树上的"+""-"不会触发.
procedure TfrmRole.cxTV_MenuMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
MyHitTest : THitTests;
tn : TTreeNode;
begin
inherited;
MyHitTest := cxTV_Menu.GetHitTestInfoAt(X,Y);
tn:=TcxTreeView(Sender).GetNodeAt(x,y);
if tn=nil then
Exit;
if htOnItem in MyHitTest then
begin
if 1 = tn.StateIndex then
begin
ChangeChildState(tn,2);
ChangeParentState(tn,2);
end
else
begin
ChangeChildState(tn,1);
ChangeParentState(tn,1);
end;
end;
end;
效果:
1 全部不选择:
[img=http://blogger.org.cn/blog/uploadfile/2008111225121107.GIF]全部不选择[/img]
2 选计量单位:
[img=http://blogger.org.cn/blog/uploadfile/2008111225049668.GIF]选计量单位[/img]
3 选资信等级
[img=http://blogger.org.cn/blog/uploadfile/2008111225213325.GIF]选资信等级[/img]
4 取消选择计量单
[img=http://blogger.org.cn/blog/uploadfile/200811122531323.GIF]取消选择计量单[/img]
5 只取消选择"计量单位修改"
[img=http://blogger.org.cn/blog/uploadfile/2008111225436615.GIF]只取消选择[/img]