Byron Whitlock
Byron Whitlock

Reputation: 53919

How do I Iterate controls in a windows form app?

SO this is a dumb question. I have added a bunch of textboxes to an options dialog in an app I've written. They are named textbox1 - textbox12. Is there a way to access the the names programmatically? I'd just like to iterate over them in a for loop. Right now I am accessing each one individually (shudders!). I know this is the wrong way. What is the right way? what is the easy way?

Thanks

Upvotes: 1

Views: 6319

Answers (5)

ICR
ICR

Reputation: 14172

Personally I prefer to create the controls programatically and then put them in a collection. i.e.

IList<TextBox> textBoxes = new List<TextBox>();

…

    for (int i = 0; i < 12; i += 1)
    {
        TextBox textBox = new TextBox();
        textBox.Position = new Point(FormMargin, FormMargin + (i * (textBox.Height + TextBoxPadding)));
        this.Controls.Add(textBox);
        this.textBoxes.Add(textBox);
    }

You can then just itterate over textBoxes to programatically add them. I find this scales better when you have several different groups of textboxes you need to do this with.

Upvotes: 2

Sterno
Sterno

Reputation: 1658

I had a page that added a variable number of checkboxes to a page via a repeater, and I needed to perform some operations on them. I ended up writing this generic extension method so I could use it for any controls in the future. This would dig down through subcontrols as well, in case your checkbox was inside some other control on the page.

public static List<TChildType> FindChildrenOfType<TChildType>(this Control currentControl)
    where TChildType : Control
{
    var childList = new List<TChildType>();
    foreach (Control childControl in currentControl.Controls)
    {
        if (childControl is TChildType)
        {
            childList.Add((TChildType)childControl);
        }

        childList.AddRange(childControl.FindChildrenOfType<TChildType>());

    }
    return childList;
}

In the page, it got used like this:

var checkedCheckboxes = _myRepeater.FindChildrenOfType<CheckBox>().FindAll(c => c.Checked);

Upvotes: 2

Lee
Lee

Reputation: 144226

The Controls collection allows you to access items by name, so you could do this:

var textboxes = Enumerable.Range(1, 12).Select(i => String.Format("textbox{0}", i)).Select(name => (TextBox)this.Controls[name]);

which will avoid having to enumerate every control in the collection, although is brittle since it depends on the naming convention used.

Alternatively you could just use the OfType query method:

var textboxes = this.Controls.OfType<TextBox>();

Upvotes: 7

John Fisher
John Fisher

Reputation: 22727

You could write a function that does this more generically.

IEnumerable<T> GetChildren<T>(Control owner)
{
    foreach (Control c in owner.Controls)
    {
        if (c is T)
        {
            yield return c as T;
        }
    }
}

Use it this way:

foreach (TextBox tb in GetChildren<TextBox>(optionsControl))
{
    System.Diagnostics.Trace.WriteLine(tb.Name);
}

Upvotes: 2

John Rudy
John Rudy

Reputation: 37858

foreach (Control c in this.Controls)
{
    if (c is TextBox)
    {
        // your logic here
    }
}

If they have different functionality, then you might need more checks than just determining that they are the correct type. And of course, this assumes that you have the System.Windows.Forms namespace imported.

Upvotes: 8

Related Questions