当我通过将连接的 TAction 设置为不可见来使组件不可见时,onupdate 事件将不再触发。要重新创建,请执行以下操作。
- 创建新的 VCL 表单应用程序
- 在表单上放置一个按钮、一个复选框和一个操作列表。
- 创建一个新操作,并将按钮连接到它。
-
为 OnExecute 和 OnUpdate 事件操作编写以下代码:
过程 TForm1.Action1Execute(Sender: TObject);
开始
ShowMessage('测试');
结尾;
过程 TForm1.Action1Update(Sender: TObject);
开始
TAction(Sender).Enabled := 不是 CheckBox1.Checked;
TAction(Sender).Visible := TAction(Sender).Enabled;
结尾;
运行应用程序。该按钮可见并且工作正常。选中该复选框,按钮就会消失。取消选中该复选框。该按钮不出现。事实上,如果您在 Action1Update 中放置断点,您将永远无法到达它。为什么会这样,我该如何解决?
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.
- Create a new VCL forms application
- Drop a button, a checkbox and an actionlist on the form.
- Create a new action, and connect the button to it.
-
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?
发布评论
评论(4)
我理解您想要做什么,并且您希望它以这种方式工作是有道理的。不过,这里有一个解决方法。
您还可以在
OnUpdate
中更新其他控件。您不限于更新接收通知的控件。因此,在确定可见性的控件的操作中,您可以在那里设置其他控件的可见性。在您的情况下,这就是复选框:创建一个新操作 (Action2) 并将其分配给 Checkbox1。
然后在复选框操作的 OnUpdate 中:
确保也将 OnExecute 分配给该复选框。像这样简单的事情就很好:
对我来说,这仍然具有逻辑意义。您将能够在一处查看其可见性依赖于所设置的复选框的所有控件。
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:
Be sure to assign an OnExecute to the checkbox as well. Something as simple as this is fine:
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.
您可以重写表单上的 InitiateAction 方法。每当应用程序空闲时就会发生这种情况,就像 OnUpdate 事件对每个操作所做的那样。
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.
无需修复此问题,它按设计工作。只有可见控件需要更新其状态,因此只有链接控件可见的操作才会更新。当您隐藏按钮时,就不再有理由更新操作。
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.
让 OnUpdate 仅调用一个单独的例程来执行所需的操作。然后您可以从其他地方调用该例程。行动列表就是为此而设计的。
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.