Change CheckBox state without calling OnClick Event
I'm wondering开发者_C百科 so when I change state of CheckBox
CheckBox->Checked=false;
It calls CheckBoxOnClick Event , how to avoid it ?
In newer Delphi versions you can use class helpers to add this functionality:
CheckBox.SetCheckedWithoutClick(False);
by using the following class helper for a VCL TCheckBox
:
TCheckBoxHelper = class helper for TCheckBox
procedure SetCheckedWithoutClick(AChecked: Boolean);
end;
procedure TCheckBoxHelper.SetCheckedWithoutClick(AChecked: Boolean);
begin
ClicksDisabled := True;
try
Checked := AChecked;
finally
ClicksDisabled := False;
end;
end;
Just for completeness: A FMX TCheckBox
will behave similar (triggering OnChange
). You can workaround this by using the following class helper:
TCheckBoxHelper = class helper for TCheckBox
procedure SetCheckedWithoutClick(AChecked: Boolean);
end;
procedure TCheckBoxHelper.SetCheckedWithoutClick(AChecked: Boolean);
var
BckEvent: TNotifyEvent;
begin
BckEvent := OnChange;
OnChange := nil;
try
IsChecked := AChecked;
finally
OnChange := BckEvent;
end;
end;
Disclaimer: Thanks, dummzeuch for the original idea. Be aware of the usual hints regarding class helpers.
You could surround the onClick event code with something like
if myFlag then
begin
...event code...
end;
If you don't want it to be executed, set myFlag to false and after the checkbox state's change set it back to true.
Another option is to change the protected ClicksDisable property using an interposer class like this:
type
THackCheckBox = class(TCustomCheckBox)
end;
procedure TCheckBox_SetCheckedNoOnClick(_Chk: TCustomCheckBox; _Checked: boolean);
var
Chk: THackCheckBox;
begin
Chk := THackCheckBox(_Chk);
Chk.ClicksDisabled := true;
try
Chk.Checked := _Checked;
finally
Chk.ClicksDisabled := false;
end;
end;
I hope there's a button solution but you could store the current event in a TNotifyEvent var, then set Checkbox.OnChecked to nil and afterwards restore it.
try this way:
Checkbox.OnClick := nil;
try
Checkbox.Checked := yourFlag;
finally
Checkbox.OnClick := CheckboxClick;
end;
Some other and much easier solution is not avoiding the the OnClick event but modifying the event handler not to respond unless the DataSet.State is in either dsEdit or dsInsert as initiated by a user triggered TDBCheckBox click e.g.:
procedure TForm1.chkSelectClick(Sender: TObject);
begin
if chkSelect.Checked = True then
if DataSource1.DataSet.State in [dsEdit,dsInsert] then
begin
{ your event handler }
end;
end;
Use the focused property to establish if the control has been clicked or the checked has been updated outside the control.
If tcheckbox.focused then
run the content of the method
else
skip the content
CheckBox.State := cbUnchecked;
works in Delphi, this doesn't fire onClickEvent
AFAIK
Simple solution is to put your onclick code in onmouseup event;
精彩评论