德尔福。如何在不触发控件事件的情况下禁用/启用控件

时间:2012-06-19 07:37:50

标签: delphi dataset controls

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

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

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

我已尝试拨打DataSet.DisableControls,但在我致电DataSet.EnableControls后立即调用了事件。

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

编辑(大图):

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

3 个答案:

答案 0 :(得分: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” - 但我不知道它是什么。

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

答案 1 :(得分:5)

一种方法是:

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

HTH

答案 2 :(得分:2)

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

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或其他一些标准,您可以将其放入检查所有组件的方法中并设置此属性。