2012-04-12 15 views
7

私は、コントロールの可視性を制御するアクションを使用しようとしています。フォームが最初のボタンが表示され、チェックボックスがチェックされている実行するとアクションを使用してコントロールの可視性を判断するにはどうすればよいですか?

パスカルファイル

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. 

フォームファイル

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 

:私のコードは次のようになります。チェックボックスをオフにすると、ボタンが消えます。チェックボックスを再度オンにすると、ボタンが再表示されません。

私はこの理由は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; 

Control.Visibleのチェックが私の行動は二度と自分自身を更新する機会を得てブロックするように表示されます。

私は問題を正しく診断しましたか?これは設計によるのですか、またはQCレポートを提出する必要がありますか?誰かが回避策を知っていますか?

+0

なぜ、あなたは['OnUpdate'](http://docwiki.embarcadero.com/Libraries/en/Vcl.ActnList.TAction.OnUpdate)を使用していますか? – TLama

+0

@tlama:これがそのためです。ほとんどの場合、 'Visible'ではなく' Enabled'を設定していると思います。 –

+0

これはバグで、少なくともMisbegotten-Featureです。任意のアクションでEnabledとVisibleを設定できる必要があります。リンクされたコントロールは、Enabled値とVisible値を含むようにリフレッシュする必要があります。ここでActionUpdateが必要な場合は、実行しようとしている種類のデカップリングが解除されます。これでチェックボックスをアクションに結合する必要があります。私は、OnUpdateを使用して可視に変更するのをやめ、単にアクションを可視または不可視に設定するだけで、onclickのチェックボックスに1行で表示します。 –

答えて

8

あなたの診断は正しいです。アクションは、最初にDelphiに導入されて以来、そのように機能しました。

私はそれが設計によるものであると考えています(おそらく、テキストや目に見えないコントロールの視覚的な側面を過剰に更新しないよう最適化しています)が、デザインが良いというわけではありません。

影響を受ける可能性があるその他のものを認識する必要がないので、影響を受けるアクションを直接操作するチェックボックスコードが含まれていると思われる回避策 - つまりOnUpdateイベントあなたのためにしてください。チェックボックスがオンになったら、Action1.Updateに電話するか、問題が解決しない場合はAction1.Visible := Trueに電話してください。

代わりに、行動更新コードをTActionList.OnUpdateイベントに追加することもできます。

+1

ありがとうございます。私はこれまで気付いていなかったことに驚いていますが、あなたがすでに問題を認識していることを安心しています。私はすでに共通の基本クラス形式で 'TCustomForm.UpdateActions'のオーバーライドを持っています。だから私はそこで仕事をして、私がそれが望むように更新を行うことができます。それはおそらく私のための最も簡単なルートです。 –

2

関連するコントロールが表示されていない場合、ActionUpdateイベントは呼び出されません。チェックボックス1のクリックイベントでアクション更新を明示的に呼び出すようにしてください。

+0

それは "行動を使用して停止"と似ています。 –

+0

デビッド。行動は良いです。しかし、Robが言ったように、あなたのシナリオでは彼らのデザインは悪いです。 –

+0

しかし、この問題を解決する最善の方法は、GUIコントロールを結合することができません。その地獄を避けることは、私が最初に行動を使用し始めた理由です。 –

4

はい、あなたの診断はRobが既に言って説明した通りです。回避策は、個々のTActionのOnUpdateイベントハンドラを使用するのではなく、TActionListのOnUpdateイベントハンドラを使用することです。

procedure TForm1.ActionList1Update(Action: TBasicAction; var Handled: Boolean); 
begin 
    Handled := True; 
    Action1.Visible := CheckBox1.Checked; 
end; 

あなたはそれ以外の場合はアクションリストのにonUpdateハンドラがどちらかと呼ばれることはありません、仕事にこれをリンクし、アクションと少なくとも一つの可視コントロールが必要です。

アクションとアクションリストが初めて導入されたとき、レイ・コノプカ(Raizeコンポーネント)は実装についての記事をいくつか書いて、それらの使い方について非常に助言しました。以来、私は個々のアクションのOnExecuteを使用するが、ActionListのOnUpdateを使用するというプラクティスを採用しました。また、ハンドラで最初に行うことは、HandledをTrueに設定して、必要以上に呼び出されないようにし、そのハンドラ内でActionのEnabledプロパティを一度変更して、GUIが結果としてちらつくことがないようにすることですそれをオフにしてからオンにします。http://edn.embarcadero.com/article/27058 Rayは自分のサイトで3つの記事を持っていましたが、エンバカデロには1つしかありませんが、「組み合わせた」バージョンである可能性があります(そうではありません)。オリジナルを手元に持っていてください)。

+2

ありがとうございます。私はレイの記事を見上げます。私は本当にリストのOnUpdateを認識していませんでしたが、コードの集中管理が良いと想像することができます。 –

+1

@DavidHeffernan:はい、コードの集中化は私がそれを使う理由です。 –

関連する問題