5

I am trying to fill an array with all the Buttons being used in Form1.

Button[] ButtonArray = new Button[5];

ButtonArray[0] = button1;   
ButtonArray[1] = button2;   
ButtonArray[2] = button3;   
ButtonArray[3] = button4;   
ButtonArray[4] = button5;

This code works fine. But if I have for example 100 buttons it is a long procedure.

Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
Clayton
  • 51
  • 3
  • 1
    If you have a design with 100 buttons then you should redesign it... – Gusman May 17 '18 at 12:35
  • 1
    Possible duplicate of [How to get ALL child controls of a Windows Forms form of a specific type (Button/Textbox)?](https://stackoverflow.com/questions/3419159/how-to-get-all-child-controls-of-a-windows-forms-form-of-a-specific-type-button) – default locale May 17 '18 at 12:50

4 Answers4

17

If all the Buttons are on the form you can try using Linq:

using System.Linq;

...

Button[] ButtonArray = Controls
  .OfType<Button>()
  .ToArray();

Edit: in case you have some buttons within groupboxes, panels (i.e. not directly on the form, but on some kind of container), you have to elaborate the code into something like this

private static IEnumerable<Button> GetAllButtons(Control control) {
  IEnumerable<Control> controls = control.Controls.OfType<Control>();

  return controls
    .OfType<Button>()
    .Concat<Button>(controls
       .SelectMany(ctrl => GetAllButtons(ctrl)));
}

...

Button[] ButtonArray = GetAllButtons(this).ToArray();

See How to get ALL child controls of a Windows Forms form of a specific type (Button/Textbox)? for details

Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
3

you can try this one:

ButtonArray[] buttonArray = new ButtonArray[this.Controls.OfType<Button>().Count()]
int i =0; //index for button array
foreach(var button in this.Controls.OfType<Button>()) //Iterate through each button control
{
    buttonArray [i++] = button;
}
Prasad Telkikar
  • 15,207
  • 5
  • 21
  • 44
  • 2
    You'd need to know how many buttons there were to start with though - Dmitry's approach doesn't require that. – Jon Skeet May 17 '18 at 12:33
  • I agreed to Dmitry's approach(elegant approach), but for newbies this can be more readable – Prasad Telkikar May 17 '18 at 12:34
  • you could simplify it by using unary operator inside of indexer `ButtonArray[i++]` – Fabjan May 17 '18 at 12:36
  • @Fabjan, Thanks for suggestions, I updated my answer – Prasad Telkikar May 17 '18 at 12:37
  • So how do you proposal initializing `ButtonArray` here? You haven't shown that, and it's pretty important. – Jon Skeet May 17 '18 at 12:38
  • 2
    That won't currently compile - it would have to be `Count()` rather than `Count`, and at this point I really don't think it's more readable than the `ToArray` answer. If someone needs to understand the `Count()` extension method to read the code, why wouldn't they understand the `ToArray()` extension method? – Jon Skeet May 17 '18 at 12:42
  • @DaisyShipton, I agreed to your point, now It seems pretty complected than the solution suggested by Dmitry – Prasad Telkikar May 17 '18 at 12:44
3

Enumerable.OfType doesn't search controls down the control-hierarchy. So if you want to find controls recursively you could use this extension method:

public static IEnumerable<T> RecursiveControlsOfType<T>(this Control rootControl) where T : Control
{
    foreach (Control child in rootControl.Controls)
    {
        if (child is T targetControl)
            yield return targetControl;
        foreach (T targetControlChild in child.RecursiveControlsOfType<T>())
            yield return targetControlChild;
    }
}

Usage:

Button[] nonRecursiveButtons = this.Controls.OfType<Button>().ToArray();
Button[] recursiveButtons = this.RecursiveControlsOfType<Button>().ToArray();
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
1
List<Button> Buttons = new List<Button>();
foreach (var item in this.Controls) // Looping through all controls in the form
{
    if (item is Button) // if the current is a button we add it
    {
        Buttons.Add(item as Button);
    }
}
Rainbow
  • 6,772
  • 3
  • 11
  • 28