我有一副地图,由n层构成(河流层,道路层......).
我想用3个checkbox分别控制图层的属性(编辑,可视,可选)
河流 checkbox[1] checkbox[2] checkbox[3]
道路 checkbox[1] checkbox[2] checkbox[3]
我应该用什么控件呢?
procedure TForm1.Button1Click(Sender: TObject);
var
R : TRect;
Widths : array of Integer;
I,Count : Integer;
CheckBox : TCheckBox;
CheckBox1: TCheckBox;
begin
Count := ListView1.Columns.Count;
SetLength(Widths,Count);
for I := 0 to Count -1 do
Widths[I] := ListView1.Columns[I].Width;
R := self.ListView1.Items[1].DisplayRect(drBounds);
R.Left := widths[1] + 2;
Dec(R.Bottom,2);
Dec(R.,2);
R.Right := Widths[0] + widths[1] - 2;
CheckBox := TCheckBox.Create(Self);
CheckBox.Parent := ListView1;
CheckBox.BoundsRect := R;
R.Left := widths[0] + widths[1] + 2;
R.Right := widths[0] + widths[1] + widths[2] - 2;
CheckBox1 := TCheckBox.Create(self);
CheckBox1.Parent := ListView1;
CheckBox1.BoundsRect := R;
end;
这是个非常简单的例子,实际上我把R的范围硬性编码了,这样不好,你修改一下,最好将代码放到OnDraw事件中去。
例:
TTreeView的结点如何具有CheckBox?
TreeView有个Images属性,做三张小图片:
全选中、部分选中、不选状态,然后在点击事件中根据具体情况设置TTreeNodes的ImageIndex就OK了。
重载TreeView的CreateParams:
type
TCheckBoxTreeView = class(TTreeView)
protected
procedure CreateParams(var Params: TCreateParams); override;
end;
procedure TCheckBoxTreeView.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.Style:=Params.Style or TVS_CHECKBOXES;
{ TVS_CHECKBOXES declared in CommCtrl }
end;
如果要Check这个CheckBox,可以用下面的代码:
function IsNodeChecked(Node :TTreeNode) :Boolean;
const
TVIS_CHECKED = $2000;
var
TvItem :TTVItem;
begin
TvItem.Mask := TVIF_STATE;
TvItem.hItem := Node.ItemId;
TreeView_GetItem(Node.TreeView.Handle, TvItem);
Result := (TvItem.State and TVIS_CHECKED) = TVIS_CHECKED;
end;
procedure SetNodeChecked(Node :TTreeNode; Checked :Boolean);
const
TVIS_CHECKED = $2000;
var
TvItem :TTVItem;
begin
FillChar(TvItem, SizeOf(TvItem), 0);
with TvItem do begin
hItem := Node.ItemId;
Mask := TVIF_STATE;
StateMask := TVIS_STATEIMAGEMASK;
if Checked then
TvItem.State :=TVIS_CHECKED
else
TvItem.State :=TVIS_CHECKED shr 1;
TreeView_SetItem(Node.TreeView.Handle, TvItem);
end;
end;
可以做成事件和封装成一个类:
private OldState :Boolean;
procedure Change(Node: TTreeNode); override;
begin
inherited Change(Node);
OldState := IsNodeChecked(Node);
end;
procedure Click; override;
var
NewState :Boolean;
begin
inherited Click;
NewState := IsNodeChecked(Self.Selected);
if NewState = OldState then Exit;
if (NewState) and Assigned(OnNodeChecked) then OnNodeChecked()
else if (not NewState) and Assigned(OnNodeUnChecked) then
OnNodeUnChecked()
// OnNodeChecked & OnNodeUnchecked will be events that you declare
end;
直接设置TreeView的节点TreeNode的StateImageIndex就可以了。它对应的StateImages为一个TImageList,且里面有三张图片,分别表达选中,部分选中,不选中三种状态即可。
//设置一个节点的状态为选中
TreeNode := TreeView.Selected;
if TreeNode <> nil then
node.StateIndex := 0;
//同样可以设置为不选中
TreeNode := TreeView.Selected;
if TreeNode <> nil then
node.StateIndex := 2;
//部分选中
TreeNode := TreeView.Selected;
if TreeNode <> nil then
node.StateIndex := 1;
很简单吧!
如果不想用StateImages(有时候可能看起来不大漂亮),也可以用ImageIndex和SelectedIndex.注意控制就可以了。