Reputation: 53919
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
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
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
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
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
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