【问题标题】:How to dinamically unbind all event handlers and rebind them after doing something?如何动态解除绑定所有事件处理程序并在做某事后重新绑定它们?
【发布时间】:2016-09-14 12:57:20
【问题描述】:

我正在寻找一种通用方法来解除所有事件处理程序的绑定,并在执行了会触发它们的操作后再次重新绑定它们。

目前,我正在使用以下特定解决方案:

var
  PrevBeforePost : TDataSetNotifyEvent;
  PrevAfterPost : TDataSetNotifyEvent;
begin
  PrevBeforePost := MyDataSet.BeforePost;
  MyDataSet.BeforePost := nil;
  PrevAfterPost := MyDataSet.AfterPost;
  MyDataSet.AfterPost := nil;

  try
    //do something that would have triggered event handlers
  finally
    MyDataSet.BeforePost := PrevBeforePost;
    MyDataSet.AfterPost := PrevAfterPost;
  end;
end;

此解决方案意味着我必须在每次需要临时禁用事件处理程序时编写特定代码,即使在我进行测试时也是如此…… 此外,很容易陷入添加其他事件而不记得在代码中禁用它们的陷阱。

有没有办法编写一个对所有组件都以相同方式工作的通用解决方案? 示例:

var
   Events : TInfosAboutEventHandlers;
begin
   Events := GetEventHandlersAndSetThemToNil(MyDataSet);
   try
     //do something that would have triggered event handlers
   finally
     SetEventHandlers(MyDataSet, Events);
   end;
end;

【问题讨论】:

  • 有人想知道是否有更好的解决方案......
  • 我的意思是如果你可以解决你的问题而不必搞砸事件处理程序。我的意思是找到一种方法来解决潜在的立场,而不会发现自己需要这样做。另一方面,如果您只需要保存两个事件处理程序,那有多难呢?如果您想要适用于所有可能组件的东西,那么人们会想知道为什么您首先要编写需要它的代码。
  • 我同意大卫的观点,这听起来很奇怪。但作为替代方案,您可以设置一个私有布尔字段,并且当该字段为真时,在每种情况下都不做任何事情。在您的代码中,您可以将其设置为 true,以便事件不执行任何操作,最后将其设置回 false,以便事件可以再次执行它们的操作。它可以工作,但有点脏
  • @DavidHeffernan:我认为这取决于每个人喜欢编写代码的方式。在大多数情况下,可以避免使用事件处理程序以支持不同的方法,但我认为有太多的场景和太多的组件可以认为没有事件处理程序就可以完成所有事情并且仍然保持干净的代码。我询问一个通用解决方案的原因有几个,首先,它可以避免每次分配新的事件处理程序时都更改代码(想象一下,您正在编辑多年来未编辑的应用程序的一部分, ...
  • 事件处理程序只是其值是过程类型的属性。这可能是识别它们的最佳方式,但在语言中,它们只是属性。你当然可以用 RTTI 和一个字典来保存这些值。如果我是你,我想我不会打扰。对我来说感觉不透明。

标签: delphi event-handling


【解决方案1】:

为什么不取消绑定它们而不是通过变量禁用它们?。

在表单上定义“禁用”变量,并在每次要避免事件时激活它。

type MyForm = class (TForm)
  ...
  private
     EventsDisabled: boolean;
  ...
end;

implementation
...
  EventsDisabled := True;
  try
    //do something that would have triggered event handlers
  finally
    EventsDisabled := False;
  end; 

现在您的事件只需要在执行任何操作之前检查该变量是否处于活动状态。

procedure TForm1.qryDataFieldNameOnChange(Sender: TObject);
begin
  if EventsDisabled then Exit;
  //actions to do when the event is triggered 
end;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-05
    • 1970-01-01
    • 2014-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-22
    • 1970-01-01
    相关资源
    最近更新 更多