让3个checkbox只能选中一个的问题(50分)

  • 主题发起人 主题发起人 sssing
  • 开始时间 开始时间
S

sssing

Unregistered / Unconfirmed
GUEST, unregistred user!
我在form窗体上面添加了3个checkbox组件,分别是:checkbox1,checkbox2,checkbox3.
然后我在checkbox1的单击事件上面添加上代码:
checkbox2.checked:=false;
checkbox3.checked:=false;

然后在checkbox2添加上代码:
checkbox1.checked:=false;
checkbox3.checked:=false;

checkbox3:
checkbox1.checked:=false;
checkbox2.checked:=false;

我想让它们三个只能选中一个,如果选中一个,其中2个即取消选中!
代码可行!但是单击某个组件的时候,其它2个组件取消了选中,但是单击的那个组件没有选中,要单击多一次才可以选中!我不知道为什么会这样!我也试过在代码上面分别加上checkbox*.checked:=true;选中自己!不行,会出错!
我也试过 checkbox*.start:=
里面的,也不行!
望高手指点!
 
你用错控件了,既然是单选的,直接用三个RADIOBUTTON就行了
 
要用一个锁变量。你这会引起连锁反应。
为什么 不用TRadioButton。
 
多么简单的一个问题:
把你的代码写在 OnMouseDown 事件中,而不是 OnClick 事件...
 
楼上的大虾们都是对的,我猜测出现问题的原因可能是你在单击checkbox1的时候执行了
checkbox2.checked:=false;
checkbox3.checked:=false;
而由于你是把代码写在OnChecked中的,所以会触发checkbox2及checkbox3的相关代码,所以你的checkbox1不会选中。
 
非要这样做也可以,干脆做个这样的例程就行啦

procedure SetCheckBoxes(aChecked: TCheckBox
const NoCheckeds: array of TCheckBox);
var
N: Integer;
Tmp1, Tmp2: TNotifyEvent;
begin
for N:= 0 to High(NoCheckeds) do with NoCheckeds[N] do begin
Tmp1:= OnClick;
Tmp2:= OnChecked;
OnClick:= nil;
OnChecked:= nil;
Checked:= False;
OnClick:= Tmp1;
OnChecked:= Tmp2;
end;
with aChecked do begin
Tmp1:= OnClick;
Tmp2:= OnChecked;
OnClick:= nil;
OnChecked:= nil;
Checked:= True;
OnClick:= Tmp1;
OnChecked:= Tmp2;
end;
end;

procedure TForm1.CheckBox1Checked(Sender: TObject);
begin
SetCheckBoxes(CheckBox1, [CheckBox2, CheckBox3]);
end;

procedure TForm1.CheckBox2Checked(Sender: TObject);
begin
SetCheckBoxes(CheckBox2, [CheckBox1, CheckBox3]);
end;

procedure TForm1.CheckBox3Checked(Sender: TObject);
begin
SetCheckBoxes(CheckBox3, [CheckBox1, CheckBox2]);
end;
 
在checkbox1的单击事件中这么写
if checkbox1.checked then
begin
checkbox2.checked:=false;
checkbox3.checked:=false;
end;
其他2个同上,这样的结果是3个可以都不选择,最多只能选择一个
 
你用错控件了,既然是单选的,直接用三个RADIOBUTTON就行了
 
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
CheckBox1: TCheckBox;
CheckBox2: TCheckBox;
CheckBox3: TCheckBox;
procedure CheckBox1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure SetChecked(Sender: TObject);
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.CheckBox1Click(Sender: TObject);
begin
SetChecked (sender);
end;

procedure TForm1.SetChecked(Sender: TObject);
var
i:Integer;
begin
for i:=ComponentCount-1 downto 0 do
begin
if Components is TCheckBox then
begin
TCheckBox(Components).OnClick:=nil ;
end;
end;

for i:=ComponentCount-1 downto 0 do
begin
if Components is TCheckBox then
begin
if TCheckBox(Components).Checked then
begin
TCheckBox(Components).Checked:=False;
end;
end;
end;

TCheckBox(sender).Checked:=true;

for i:=ComponentCount-1 downto 0 do
begin
if Components is TCheckBox then
begin
TCheckBox(Components).OnClick:=SetChecked ;
end;
end;
end;

end.
 
又是一个不结贴的!
 
解决方法在讨论中已经给出了至少三种,感觉最快捷方便的是在控件中捕捉鼠标单击事件,楼主估计是写出事件了,因为第一次单击是选中控件,然后再单击才响应你所选中控件的单击事件。
 
让CheckBox1,2,3的OnClick事件都指向同一个事件
procedure TForm1.CheckBox1Click(Sender: TObject);
const
MAX = 3;
var
ArrCheckBox: array[0..MAX - 1] of TCheckBox;
i, k: integer;
begin
if not TCheckBox(Sender).Checked then exit;
//
k:= -1;
for i:= 0 to MAX - 1 do
begin
ArrCheckBox:= TCheckBox(FindComponent('CheckBox' + IntToStr(i + 1)));
if ArrCheckBox = Sender then k:= i;
end;
if k < 0 then exit;
//
for i:= 0 to MAX - 1 do
if (i <> k) and ArrCheckBox[k].Checked then
ArrCheckBox.Checked:= false;
end;
 
来自:vvyang, 时间:2008-8-6 20:01:06, ID:3912893
多么简单的一个问题:
把你的代码写在 OnMouseDown 事件中,而不是 OnClick 事件...

说得很对 或者干脆用 TRadioButton。
 
又是一个不结贴的!强烈鄙视!
 
RadioGroup上放RadioButton
不需要任何代码
 
后退
顶部