更改复选框状态而不调用 OnClick 事件

发布于 2024-08-21 12:12:53 字数 126 浏览 6 评论 0原文

我想知道当我更改 CheckBox 的状态时

CheckBox->Checked=false;

它会调用 CheckBoxOnClick Event ,如何避免它?

I'm wondering so when I change state of CheckBox

CheckBox->Checked=false;

It calls CheckBoxOnClick Event , how to avoid it ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

赠佳期 2024-08-28 12:12:54

有时

需要更改 TCheckBox 组件的状态,但无需操作 OnClick 事件。这个任务可以这样解决:

{设置一个已检查}

yourCheckBox.Perform(BM_SETCHECK, 1, 0);

{设置一个未检查}

yourCheckBox.Perform(BM_SETCHECK, 0, 0);

foudn this on scalabium.com

Sometimes it's necessary to change a state of TCheckBox component, but without operation of OnClick event. This task can be solved so:

{set a checked}

yourCheckBox.Perform(BM_SETCHECK, 1, 0);

{set a unchecked}

yourCheckBox.Perform(BM_SETCHECK, 0, 0);
一梦等七年七年为一梦 2024-08-28 12:12:54

CheckBox.State := cbUnchecked; 在 Delphi 中工作,这不会触发 onClickEvent AFAIK

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

不必了 2024-08-28 12:12:53

在较新的 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 的原始想法。请注意有关类助手的常见提示。

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.

一腔孤↑勇 2024-08-28 12:12:53

您可以用类似的内容包围 onClick 事件代码,

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

如果您不想执行它,请将 myFlag 设置为 false,并在复选框状态更改后将其设置回 true。

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.

不甘平庸 2024-08-28 12:12:53

另一种选择是使用插入器类更改受保护的 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;

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;
无言温柔 2024-08-28 12:12:53

我希望有一个按钮解决方案,但您可以将当前事件存储在 TNotifyEvent var 中,然后将 Checkbox.OnChecked 设置为 nil,然后恢复它。

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.

枉心 2024-08-28 12:12:53

尝试这样:

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

try this way:

Checkbox.OnClick := nil;
try
  Checkbox.Checked := yourFlag;
finally
  Checkbox.OnClick := CheckboxClick;
end;
没有你我更好 2024-08-28 12:12:53

使用 focus 属性来确定控件是否已被单击或选中的内容是否已在控件外部更新。

如果 tcheckbox.focused 那么

 run the content of the method

else

skip the content 

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 
心凉 2024-08-28 12:12:53

其他一些更简单的解决方案不是避免 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;

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;
猫性小仙女 2024-08-28 12:12:53

简单的解决方案是将 onclick 代码放在 onmouseup 事件中;

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文