如何使用动作确定控件的可见性? [英] How can I use an action to determine a control's visibility?
问题描述
我正在尝试使用动作来控制控件的可见性。我的代码如下所示:
Pascal文件
unit Unit1;
接口
使用
Windows,消息,SysUtils,变体,类,图形,控件,表单,对话框,ActnList,StdCtrls;
type
TForm1 = class(TForm)
Button1:TButton;
ActionList1:TActionList;
Action1:TAction;
CheckBox1:TCheckBox;
procedure Action1Update(Sender:TObject);
结束
var
Form1:TForm1;
实现
{$ R * .dfm}
程序TForm1.Action1Update(发件人:TObject);
begin
(发件人为TAction).Visible:= CheckBox1.Checked;
结束
结束。
表单文件
对象Form1:TForm1
对象Button1:TButton
Left = 8
顶部= 31
Action = Action1
end
对象CheckBox1:TCheckBox
顶部= 8
Caption ='CheckBox1'
Checked = True
状态= cbChecked
结束
对象ActionList1:TActionList
左= 128
顶部= 8
对象Action1:TAction
Caption ='Action1'
OnUpdate = Action1Update
结束
结束
结束
当表单首次运行时,按钮是可见的,该复选框被选中。然后我取消选中复选框,按钮消失。当我重新检查复选框时,按钮无法重新出现。
我认为这样做的原因可以在 TCustomForm.UpdateActions
:
procedure TraverseClients(Container:TWinControl);
var
I:整数;
控制:TControl;
begin
如果Container.Showing而不是(csDesigning在Container.ComponentState)然后
为I:= 0到Container.ControlCount - 1 do
begin
控制: = Container.Controls [I];
if(csActionClient in Control.ControlStyle)和Control.Visible then
Control.InitiateAction;
if(Control是TWinControl)和(TWinControl(Control).ControlCount> 0)然后
TraverseClients(TWinControl(Control));
结束
结束
对 Control.Visible
的检查显示为阻止我的行动有机会再次更新。
我是否正确地诊断了问题?这是设计还是提交QC报告?有人知道解决方法吗?
您的诊断是正确的。我们期望它是按设计(优化,以避免文本和其他视觉方面的无形控件的过度更新)的优化。 ,可能),但这并不意味着设计是好的。
我可以想象的任何解决方法将涉及您的复选框代码直接操纵受影响的操作,这不是非常优雅,因为它不应该知道其他可能会影响的东西 - 这就是$ code> OnUpdate 事件应该为您做的事情。当复选框被选中时,调用 Action1.Update
,或者如果不起作用,那么 Action1.Visible:= True
。
你也可以把你的动作更新代码放在 TActionList.OnUpdate
事件中。 p>
I'm trying to use an action to control the visibility of a control. My code looks like this:
Pascal file
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ActnList, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
ActionList1: TActionList;
Action1: TAction;
CheckBox1: TCheckBox;
procedure Action1Update(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Action1Update(Sender: TObject);
begin
(Sender as TAction).Visible := CheckBox1.Checked;
end;
end.
Form file
object Form1: TForm1
object Button1: TButton
Left = 8
Top = 31
Action = Action1
end
object CheckBox1: TCheckBox
Left = 8
Top = 8
Caption = 'CheckBox1'
Checked = True
State = cbChecked
end
object ActionList1: TActionList
Left = 128
Top = 8
object Action1: TAction
Caption = 'Action1'
OnUpdate = Action1Update
end
end
end
When the form first runs the button is visible and the check box is checked. Then I un-check the check box and the button disappears. When I re-check the check box the button fails to re-appear.
I think the reason for this can be found inside the following local function in TCustomForm.UpdateActions
:
procedure TraverseClients(Container: TWinControl);
var
I: Integer;
Control: TControl;
begin
if Container.Showing and not (csDesigning in Container.ComponentState) then
for I := 0 to Container.ControlCount - 1 do
begin
Control := Container.Controls[I];
if (csActionClient in Control.ControlStyle) and Control.Visible then
Control.InitiateAction;
if (Control is TWinControl) and (TWinControl(Control).ControlCount > 0) then
TraverseClients(TWinControl(Control));
end;
end;
The check of Control.Visible
appears to block my action ever getting a chance to update itself again.
Have I diagnosed the issue correctly? Is this by design or should I submit a QC report? Does anyone know of a workaround?
Your diagnosis is correct. Actions have worked that way since they were first introduced to Delphi.
I expect it's by design (an optimization to avoid excessive updating of the text and other visual aspects of invisible controls, probably), but that doesn't mean the design is good.
Any workaround I can imagine will involve your checkbox code directly manipulating the affected actions, which isn't very elegant since it shouldn't have to be aware of everything else it might affect — that's what the OnUpdate
event is supposed to do for you. When the checkbox gets checked, call Action1.Update
, or if that doesn't work, then Action1.Visible := True
.
You could also put your action-updating code in the TActionList.OnUpdate
event instead.
这篇关于如何使用动作确定控件的可见性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!