Change CheckBox state without calling OnClick Even

2019-04-19 12:51发布

问题:

I'm wondering so when I change state of CheckBox

CheckBox->Checked=false;

It calls CheckBoxOnClick Event , how to avoid it ?

回答1:

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.



回答2:

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;


回答3:

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.



回答4:

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.



回答5:

try this way:

Checkbox.OnClick := nil;
try
  Checkbox.Checked := yourFlag;
finally
  Checkbox.OnClick := CheckboxClick;
end;


回答6:

Simple solution is to put your onclick code in onmouseup event;



回答7:

CheckBox.State := cbUnchecked; works in Delphi, this doesn't fire onClickEvent AFAIK