14

たくさんのコントロールを含むフォームがあり、特定のパネルのすべてのコントロールを反復処理して、それらを有効/無効にしたいと考えていました。

私はこれを試しました:

var component: TComponent;
begin
  for component in myPanel do
    (component as TControl).Enabled := Value;
end;

しかし、それは何もしませんでした。すべてのコンポーネントは、親オブジェクトではなく、フォームのコンポーネント コレクションにあることがわかります。コントロール内のすべてのコントロールを取得する方法があるかどうか、誰かが知っていますか? (このような醜い回避策に加えて、これは私がしなければならなかったことです):

var component: TComponent;
begin
  for component in myPanel do
    if (component is TControl) and (TControl(component).parent = myPanel) then
      TControl(component).Enabled := Value;
end;

誰か良い方法を教えてください...

4

6 に答える 6

26

TWinControl.Controls配列と付随するControlCountプロパティを探しています。これらは、コントロールの直接の子用です。孫などを取得するには、標準の再帰手法を使用します。

一般に、親子関係とは何Componentsの関係もないため、配列(for-ループが反復するもの)は本当に必要ありません。inコンポーネントは子関係を持たないものを所有でき、コントロールは所有していない子を持つことができます。

また、コントロールを無効にすると、そのすべての子も暗黙的に無効になることに注意してください。無効なコントロールの子と対話することはできません。OS は入力メッセージを送信しません。ただし、それらを無効にするには、個別に無効にする必要がありますつまり、ボタンのテキストを灰色にするには、ボタンがマウス クリックに反応しなくても、その親を無効にするだけでは十分ではありません。ボタン自体を「無効に」ペイントするには、ボタン自体を無効にする必要があります。

于 2009-01-05T23:41:09.277 に答える
13

パネルを無効にすると、そのパネル上のすべてのコントロールも無効になります。

匿名メソッドを使用した再帰的ソリューション:

type
  TControlProc = reference to procedure (const AControl: TControl);

procedure TForm6.ModifyControl(const AControl: TControl; 
  const ARef: TControlProc);
var
  i : Integer;
begin
  if AControl=nil then
    Exit;
  if AControl is TWinControl then begin
    for i := 0 to TWinControl(AControl).ControlCount-1 do
      ModifyControl(TWinControl(AControl).Controls[i], ARef);
  end;
   ARef(AControl);
end;

procedure TForm6.Button1Click(Sender: TObject);
begin
  ModifyControl(Panel1,
    procedure (const AControl: TControl)
    begin
      AControl.Enabled := not Panel1.Enabled;
    end
  );
end;
于 2009-01-05T23:44:29.957 に答える
2

Delphi 2007 の方法を次に示します。

procedure TForm6.ModifyControl(const AControl: TControl; const value: Boolean);
var
  i: Integer;
begin
  if AControl=nil then Exit;
  if AControl is TWinControl then begin
    for i := 0 to TWinControl(AControl).ControlCount-1 do
      ModifyControl(TWinControl(AControl).Controls[i], value);
  end;
  Acontrol.Enabled := value;
end;

procedure TForm6.Button1Click(Sender: TObject); 
begin 
  ModifyControl(Panel1, true);  // true or false
end;
于 2012-03-24T18:46:28.713 に答える
1

単に

Panel.Enabled := Value;
于 2009-01-06T01:36:48.920 に答える
0

この投稿が少し古いことは知っていますが、同じ情報を検索してここに来ました。これは、興味のある人のために私が作成した C++ コードです。

// DEV-NOTE:  GUIForm flattens the VCL controls
// VCL controls are nested.  I.E. Controls on a
// Panel would have the Panel as a parent and if
// that Panel is on a TForm, TForm's control count
// does not account for the nested controls on the
// Panel.
//
// GUIControl is passed a Form pointer and an index
// value, the index value will walk the controls on the
// form and any child controls counting up to the idx
// value passed in.  In this way, every control has a
// unique index value
//
// You can use this to iterate over every single control
// on a form.  Here is example code:
//
// int count = 0;
// TForm *pTForm = some_form
// TControl *pCtrl = 0;
// do
// {
//      pCtrl = GUIControl(pTForm, count++);
//
// }while(pCtrl);

TControl *GUIControl(TForm *F, int idx)
{
    TControl *rval = 0;
    int RunCount = 0;

    for(int i=0; i<F->ControlCount && !rval; i++)
    {
        TControl *pCtl = F->Controls[i];

        if(RunCount == idx )
            rval = pCtl;
        else
            rval = GUIChildControl( pCtl, RunCount, idx);

        RunCount++;
    }

    return(rval);
}

TControl *GUIChildControl(TControl *C, int &runcount, int idx)
{
    TControl *rval = 0;
    TWinControl *pC = dynamic_cast<TWinControl *>(C);
    if(pC)
    {
        for(int i=0; i<pC->ControlCount && !rval; i++)
        {
            TControl *pCtrl = pC->Controls[i];
            runcount++;

            if( runcount == idx)
                rval = pCtrl;
            else
            {
                TWinControl *pCC = dynamic_cast<TWinControl *>(pCtrl);

                if(pCC)
                {
                    if( pCC->ControlCount )
                        rval = GUIChildControl(pCtrl, runcount, idx);
                }
            }
        }
    }

    return(rval);
}
于 2013-12-04T16:43:44.330 に答える