2

我有一个 DataSet ( TZQuery),它有几个布尔字段,分配有 TDBCheckBoxes。

这些复选框具有OnClick分配给它们的“”事件,并且每当我更改字段值(分配给复选框)时都会触发它们。

问题是我不需要触发这些事件,在我对数据集进行的许多操作中。

我试过打电话DataSet.DisableControls,但在我打电话后立即调用事件DataSet.EnableControls

所以我的问题是 - 有没有办法禁用触发数据感知控件事件。

编辑(大图):

如果在保存数据时发生异常,我必须加载默认值(或我在保存之前拥有的值)。现在,在加载该数据时,所有这些事件(TDBCheckBoxes 和其他数据感知控件)都会被触发,这些事件会执行各种操作,这些操作会产生延迟,有时甚至是不需要的数据更改,我正在寻找一种通用的解决方案来禁用它们短时间内。

4

3 回答 3

6

基于 Guillem 的帖子:

关闭一切:

使用 for 循环遍历表单上的每个组件,如下所示,将属性更改为所需的值。

如果您想稍后恢复到原始属性值,则必须保存原始值(因为下面使用了 OldEvent。)

编辑:下面的代码显示了正在讨论的关键概念。如果在运行时添加或删除组件,或者如果您想使用绝对最少的内存量,那么使用动态数组,正如 Pieter 建议的那样,存储指向组件的指针而不是索引它们。

  const
    MAX_COMPONENTS_ON_PAGE = 100; // arbitrarily larger than what you'd expect. (Use a dynamic array if this worries you.
  var 
     OldEvent: Array[0.. MAX_COMPONENTS_ON_PAGE - 1] of TNotifyEvent; // save original values here
     i: Integer;
  begin                                 
   for i := 0 to ComponentCount - 1 do 
   begin
     if (Components[i] is TCheckBox)  then 
        begin
          OldEvent[i] := TCheckBox(Components[i]).OnClick; // remember old state  
          TCheckBox(Components[i]).OnClick := nil;
        end
      else if (Components[i] is TEdit) then
         begin
           OldEvent[i] := TEdit(Components[i]).OnClick; // remember old state  
           TEdit(Components[i]).OnClick := nil;          
         end;
    end;

恢复到以前的值

 for i := 0 to ComponentCount - 1 do 
 begin
   if (Components[i] is TCheckBox)  then
      TCheckBox(Components[i]).OnClick := OldEvent[i]
   else if (Components[i] is TEdit)  then
      TEdit(Components[i]).OnClick := OldEvent[i];
 end;

可能有一种方法可以将所有 if 语句折叠到一个通用测试中,该测试回答“这个组件是否有 OnClickEvent”——但我不知道它是什么。

希望有人会建设性地批评我的回答(而不是仅仅投反对票。)但是,希望我上面展示的内容是可行的。

于 2012-06-19T12:10:51.527 回答
5

一种方法如下:

var
  Event : TNotifyEvent;    
begin
  Event := myCheckbox.OnClick;
  try
    myCheckbox.OnClick := nil;
    //your code here
  finally
    myCheckbox.OnClick := Event;
  end;
end;

高温高压

于 2012-06-19T07:57:17.463 回答
2

的内部设计是每次属性更改时都会TCustomCheckBox触发该方法。无论是通过实际单击它还是在代码中设置它。当您调用时,这里就会发生这种情况,因为控件会更新以显示数据集中链接字段的值。ClickCheckedEnableControls

TButtonControlTCustomCheckBox继承自)具有属性ClicksDisabled. 使用它来代替(或补充) DisableControls/EnableControls 调用。不幸的是,它受到保护并且未被公开,TCustomCheckBox但您可以使用一个小黑客来访问它:

type
  TButtonControlAccess = class(TButtonControl)
  public
    property ClicksDisabled;
  end;

...

TButtonControlAccess(MyCheckBox1).ClicksDisabled := True;
// do some dataset stuff
TButtonControlAccess(MyCheckBox1).ClicksDisabled := False;

当然,如果控件继承自TCustomCheckBox或某些其他条件,您可以将其放入检查所有组件并设置此属性的方法中。

于 2012-06-19T18:54:19.930 回答