为啥不为不可见组件触发 OnUpdate [重复]

Posted

技术标签:

【中文标题】为啥不为不可见组件触发 OnUpdate [重复]【英文标题】:Why doesn't OnUpdate trigger for invisible components [duplicate]为什么不为不可见组件触发 OnUpdate [重复] 【发布时间】:2011-12-09 14:44:08 【问题描述】:

当我通过将连接的 TAction 设置为不可见使组件不可见时,onupdate 事件将不再触发。要重新创建,请执行以下操作。

    创建一个新的 VCL 表单应用程序 在表单上放置一个按钮、一个复选框和一个操作列表。 创建一个新动作,并将按钮连接到它。

    为动作 OnExecute 和 OnUpdate 事件编写以下代码:

    procedure TForm1.Action1Execute(Sender: TObject);
    begin
      ShowMessage('Test');
    end;
    
    procedure TForm1.Action1Update(Sender: TObject);
    begin
      TAction(Sender).Enabled := not CheckBox1.Checked;
      TAction(Sender).Visible := TAction(Sender).Enabled;
    end;
    

运行应用程序。该按钮是可见的,并且可以正常工作。选中复选框,按钮消失。取消选中复选框。按钮不出现。事实上,如果您在 Action1Update 中放置断点,您将永远无法到达它。为什么会这样,我该如何解决?

【问题讨论】:

***.com/questions/10127685/…有更好的回答这个问题 【参考方案1】:

无需解决此问题,它按设计工作。只有可见控件需要更新其状态,因此只有链接控件可见的操作才会更新。当您隐藏按钮时,没有更多理由更新操作。

【讨论】:

所以唯一的解决办法是不要将其设置为不可见?就我而言,当满足某些条件时,我想让一些按钮不可见而不是不可见。当这些条件发生变化时,我想让按钮再次可见。我可以手动执行此操作,但我更愿意在操作上使用 OnUpdate。 您可以在复选框的点击处理程序中手动更新操作(通过调用Action.Update;)。 @TOndrej:这违背了使用 Actions 的目的。 使用保存动作的动作列表的 OnUpdate 处理程序...只要确保它至少有一个链接到可见控件的动作。 (别忘了设置Handled := True; 否则你的处理程序会被调用太多次)。 这并没有违背使用动作的目的,@Afrazier。使用操作的目的是将 UI 与业务逻辑分开。调用 Action.Update 不会影响这一点。调用 Update 的人不必知道操作附加了哪些控件。不过,它在某种程度上违背了 OnUpdate 事件的目的,因为这意味着一个动作可以对自己进行一些更新,从而有效地削减自己的膝盖。【参考方案2】:

让 OnUpdate 调用一个单独的例程来执行所需的操作。然后,您可以从其他地方调用该例程。操作列表就是为此而设计的。

【讨论】:

【参考方案3】:

我了解您想要做什么,并且您希望它以这种方式工作是有道理的。但是,这里有一个解决方法。

您也可以更新OnUpdate 中的其他控件。您不仅限于更新接收通知的控件。因此,在确定可见性的控件的操作中,您可以在那里设置其他控件的可见性。在您的情况下,这就是复选框:

创建一个新动作(Action2)并将其分配给 Checkbox1。

然后在复选框动作的 OnUpdate 中:

procedure TForm1.Action2Update(Sender: TObject);
begin
  Button1.Visible := TAction(Sender).Checked;
end;

请务必也为复选框分配 OnExecute。像这样简单的事情就可以了:

procedure TForm1.Action2Execute(Sender: TObject);
begin
  TAction(Sender).Checked := not TAction(Sender).Checked;
end;

对我来说,这仍然合乎逻辑。您将能够在一个地方查看所有控件,其可见性取决于所设置的复选框。

【讨论】:

【参考方案4】:

您可以覆盖表单上的 InitiateAction 方法。每当应用程序空闲时都会发生这种情况,就像 OnUpdate 事件对每个操作所做的那样。

【讨论】:

以上是关于为啥不为不可见组件触发 OnUpdate [重复]的主要内容,如果未能解决你的问题,请参考以下文章

反应,为啥标签不为复选框触发 onChange?

防止触发 WidgetProvider 的 onUpdate

Firebase Cloud 函数触发两次 onUpdate

Qt的高手们,向你们请教: Qt界面的一个控件,比如说一个GroupBox,如何在其刚开始运行时为不可见,点击按

AppWidgetProvider - 每次对任何 AppWidget 文件进行更改时都会触发 onUpdate 吗?

js 怎么判断a标签的href为不为空或者 为不为# 给出提示框 转页面