Tuesday, March 15, 2011

Is there any way to get all the controls on a container control?

I've got a form with a bunch of controls on it, and I wanted to iterate through all the controls on a certain panel and enable/disable them.

I tried this:

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

But that did nothing. Turns out all components are in the form's component collection, not their parent object's. So does anyone know if there's any way to get all the controls inside a control? (Besides an ugly workaround like this, which is what I ended up having to do):

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

Someone please tell me there's a better way...

From stackoverflow
  • You're looking for the TWinControl.Controls array and the accompanying ControlCount property. Those are for a control's immediate children. To get grandchildren etc., use standard recursive techniques.

    You don't really want the Components array (which is what the for-in loop iterates over) since it has nothing to do, in general, with the parent-child relationship. Components can own things that have no child relationship, and controls can have children that they don't own.

    Also note that disabling a control implicitly disables all its children, too. You cannot interact with the children of a disabled control; the OS doesn't send input messages to them. To make them look disabled, though, you'll need to disable them separately. That is, to make a button have grayed text, it's not enough to disable its parent, even though the button won't respond to mouse clicks. You need to disable the button itself to make it paint itself "disabledly."

    Mason Wheeler : Thank you. That's exactly what I was looking for.
    gabr : Once I wrote Controls[] enumerator. You can find it at http://17slon.com/blogs/gabr/2008/02/twincontrolcontrols-enumerator.html.
  • If you disable a panel, al controls on it are disabled too.

    Recursive solution with anonymous methods:

    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;
    
    Mason Wheeler : Very nice. Unfortunately, we don't have D2009 yet here at work. :(
  • Panel.Enabled := Value

1 comments:

Unknown said...

The topic is totally new for me. I want to understand the topic but how I don't know ? Please share some more post regarding this and explain in detailed form in easy way.
electronic signature software

Post a Comment