如何使用动作确定控件的可见性? [英] How can I use an action to determine a control's visibility?

查看:115
本文介绍了如何使用动作确定控件的可见性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用动作来控制控件的可见性。我的代码如下所示:



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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆