Why doesn't OnUpdate trigger for invisible components [duplicate]

眉间皱痕 提交于 2019-12-22 18:17:31

问题


When I make a component invisible by setting the connected TAction to invisible, the onupdate event will not trigger anymore. To recreate, do the following.

  1. Create a new VCL forms application
  2. Drop a button, a checkbox and an actionlist on the form.
  3. Create a new action, and connect the button to it.
  4. Write the following code for the actions OnExecute and OnUpdate event:

    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;
    

Run the application. The button is visible, and works properly. Check the checkbox, and the button disappears. Uncheck the checkbox. The button doesn't appear. In fact, if you put a breakpoint in Action1Update, you'll never get to it. Why is this, and how do I fix it?


回答1:


No need to fix this, it works as designed. Only visible controls need to update their state, so only actions whose linked controls are visible are updated. When you hide the button there's no more reason to update the action.




回答2:


Have the OnUpdate only call a separate routine that does what is required. Then you can call that routine from other places. Action lists were designed for that.




回答3:


I understand what you're trying to do, and it makes sense that you would want it to work that way. However, here's a workaround for the way it does work.

You can update other controls in an OnUpdate also. You're not limited to updating the control that receives the notification. So, in the action for the control that determines visibility, you can set the visibility of the other controls there. In your case, that's the checkbox:

Create a new action (Action2) and assign it to Checkbox1.

Then in the checkbox action's OnUpdate:

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

Be sure to assign an OnExecute to the checkbox as well. Something as simple as this is fine:

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

To me, this still makes logical sense. You'll be able to look in one spot to see all of the controls whose visibility relies on that checkbox being set.




回答4:


You can override the InitiateAction method on the form. This will happen whenever the application goes idle, just as on OnUpdate event does for each action.



来源:https://stackoverflow.com/questions/8447127/why-doesnt-onupdate-trigger-for-invisible-components

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!