不调用OnClick事件改变CheckBox状态

14

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

CheckBox->Checked=false;

它调用了CheckBoxOnClick事件,如何避免它?


通过在.text属性中使用带有✓的tButton。高度和宽度为25x25,因此看起来像复选框。从.text为空开始。当按下按钮时,标签将更改为✓。onClick可以测试标签是否为空或为✓标记。使用if mylabel.text ='' then ...将文本更改为✓,否则mylabel.text:='✓'。就是这样。在代码的任何其他地方,您都可以读取mylabel.text值以查看它是否为✓。我发现,在使用样式表时,对于我来说没有办法在form.create上处于未选中状态的复选框周围。好的解决方案,希望它能帮到你。 - Winston
9个回答

11

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


这正是我正在寻找的!!谢谢 - KryNaC

10

另一种选项是使用一个类似这样的中介类来更改受保护的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;

10

你可以将onClick事件代码用类似这样的方式包围起来:

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

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


是的... :-S 那真的很容易。不知道为什么我自己没想到 >_< - cnd

7

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


CheckBox->Checked=false 是在按钮上,但它仍然调用了 onClick 事件。所以我会尝试一下。谢谢。 - cnd

4
尝试这种方式:
Checkbox.OnClick := nil;
try
  Checkbox.Checked := yourFlag;
finally
  Checkbox.OnClick := CheckboxClick;
end;

对我来说起作用了。看起来这是最简单的解决方案。 - felipeaf

2

使用 focused 属性来确定控件是否已被单击或已在控件外部更新了 checked 属性。

如果 tcheckbox.focused,则

 run the content of the method

否则
skip the content 

1

还有一种更简单的解决方案,不是避免OnClick事件,而是修改事件处理程序,除非DataSet.State处于由用户触发的TDBCheckBox点击引起的dsEdit或dsInsert状态,否则不做出响应,例如:

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;

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

-1

CheckBox.State := cbUnchecked; 在 Delphi 中有效,据我所知,这不会触发 onClickEvent


我也这么想,但在XE7中尝试将State设置为CBChecked或CBUnchecked会触发OnClickEvent。 - David Bolton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接