Изменить состояние CheckBox без вызова события OnClick

Мне так интересно, когда я меняю состояние CheckBox

CheckBox->Checked=false;

Он вызывает событие CheckBoxOnClick, как его избежать?

9 ответов

Решение

Вы можете окружить код события onClick чем-то вроде

if myFlag then
  begin
    ...event code...
  end;

Если вы не хотите, чтобы он выполнялся, установите для myFlag значение false, а после изменения состояния флажка установите для него значение true.

В более новых версиях Delphi вы можете использовать помощники классов для добавления этой функциональности:

CheckBox.SetCheckedWithoutClick(False);

с помощью следующего помощника класса для 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;

Просто для полноты: FMX TCheckBox будет вести себя аналогично OnChange). Вы можете обойти это, используя следующий помощник класса:

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;

Отказ от ответственности: Спасибо, dummzeuch за оригинальную идею. Знайте об обычных подсказках относительно помощников класса.

Другой вариант - изменить защищенное свойство ClicksDisable, используя класс вставки:

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;

Я надеюсь, что есть решение для кнопки, но вы можете сохранить текущее событие в переменной TNotifyEvent, затем установить для Checkbox.OnChecked значение nil и затем восстановить его.

Попробуйте так:

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

Используйте сфокусированное свойство, чтобы установить, был ли щелкнут элемент управления или флажок был обновлен за пределами элемента управления.

Если tcheckbox.focused, то

       run the content of the method

еще

      skip the content 

Некоторое другое и гораздо более простое решение не позволяет избежать события OnClick, но изменяет обработчик событий, чтобы он не отвечал, если DataSet.State не находится в dsEdit или dsInsert по инициативе пользователя, запускаемого щелчком TDBCheckBox, например:

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;

CheckBox.State := cbUnchecked; работает в Delphi, это не сработает onClickEvent насколько мне известно

Простое решение - поместить ваш код onclick в событие onmouseup;

Другие вопросы по тегам