Loop through Textboxes

57,015

Solution 1

To get all controls and sub-controls recursively of specified type, use this extension method:

public static IEnumerable<TControl> GetChildControls<TControl>(this Control control) where TControl : Control
{
    var children = (control.Controls != null) ? control.Controls.OfType<TControl>() : Enumerable.Empty<TControl>();
    return children.SelectMany(c => GetChildControls<TControl>(c)).Concat(children);
}

usage:

var allTextBoxes = this.GetChildControls<TextBox>();
foreach (TextBox tb in allTextBoxes)
{
    tb.Text = ...;
}

Solution 2

You Could loop all the controls in the form asking one by one if it is a "Textbox" y ther return the complete List of them.

public List GetTextBoxes(){   
    var textBoxes = new List();   
        foreach (Control c in Controls){   
            if(c is TextBox){   
                textBoxes.add(c);   
        }   
    }   
return textBoxes;   
}

Solution 3

Since this post seems to resurrect itself from time to time and since the solutions above do not find controls inside of controls, such as in a groupbox, this will find them. Just add your control type:

    public static IList<T> GetAllControls<T>(Control control) where T : Control
    {
        var lst = new List<T>();
        foreach (Control item in control.Controls)
        {
            var ctr = item as T;
            if (ctr != null)
                lst.Add(ctr);
            else
                lst.AddRange(GetAllControls<T>(item));

        }
        return lst;
    }

And it's use:

        var listBoxes = GetAllControls<ListBox>(this);
        foreach (ListBox lst in listBoxes)
        {
            //Do Something
        }

Solution 4

You can loop through the textboxes in your form in a fairly simple manner:

Func<ControlCollection, List<TextBox>> SearchTextBoxes = null;
SearchTextBoxes = coll => {
    List<TextBox> textBoxes = new List<TextBox>();

    foreach (Control c in coll) {
        TextBox box = c as TextBox;
        if (box != null)
           textBoxes.Add(box);
        if (c.Controls.Count > 0)
           textBoxes.AddRange(SearchTextBoxes(c.Controls));
    }

    return textBoxes;
};

var tbs = SearchTextBoxes(this.Controls).OrderBy(tb => tb.Name);

Edit: Changed according to new requirements. Not nearly as elegant as the LINQ-solution, of course :)

Solution 5

Iterate through controls within form and check name of the control if matched then set Text property as you require.

int i = 0;
foreach (Control contrl in this.Controls) {
    if (contrl.Name == ("DateTextBox" + i.ToString())) {
        contrl.Text = "requiredtexttobeset";
    }
    i = i + 1;
}
Share:
57,015
Taryn
Author by

Taryn

developer, techie, nerd.... ex-DBRE at Stack Overflow, previously a Community Manager for Stack Overflow. When I'm not at my desk, I do CrossFit and run (a lot).

Updated on July 03, 2020

Comments

  • Taryn
    Taryn almost 4 years

    I have a winforms app that has 37 textboxes on the screen. Each one is sequentially numbered:

    DateTextBox0
    DateTextBox1 ...
    DateTextBox37
    

    I am trying to iterate through the text boxes and assign a value to each one:

    int month = MonthYearPicker.Value.Month;
    int year = MonthYearPicker.Value.Year;
    int numberOfDays = DateTime.DaysInMonth(year, month);
    
    m_MonthStartDate = new DateTime(year, month, 1);
    m_MonthEndDate = new DateTime(year, month, numberOfDays);
    
    DayOfWeek monthStartDayOfWeek = m_MonthStartDate.DayOfWeek;
    int daysOffset = Math.Abs(DayOfWeek.Sunday - monthStartDayOfWeek);
    
    for (int i = 0; i <= (numberOfDays - 1); i++)
    {
     //Here is where I want to loop through the textboxes and assign values based on the 'i' value
       DateTextBox(daysOffset + i) = m_MonthStartDate.AddDays(i).Day.ToString();
    }
    

    Let me clarify that these textboxes appear on separate panels (37 of them). So in order for me to loop through using a foreach, I have to loop through the primary controls (the panels), then loop through the controls on the panels. It starts getting complicated.

    Any suggestions on how I can assign this value to the textbox?

  • Fredrik Mörk
    Fredrik Mörk over 13 years
    That will miss any controls that are not located directly on the form (such as in a panel, tab page or similar).
  • Taryn
    Taryn over 13 years
    I know I can loop through the controls but this screen contains 37 panels with the DateTextBoxes as well as another control. So in order for me to get the data I have to loop through the panel controls and then the controls in the panel to get an array. Is there a way for me to do this without using an array? Just assign the DateTextBoxes the data it needs?
  • abatishchev
    abatishchev over 13 years
    @bluefeet: See my answer to find how to loop through nested controls
  • Christian
    Christian over 13 years
    Well, having them in panels changes things "a bit". You need to go recursive about it. Or even better, use the answer that abatishchev provided. It's pretty neat :)
  • Fredrik Mörk
    Fredrik Mörk over 13 years
    +1 - that is almost exactly the code that I was about to post.
  • HelpNeeder
    HelpNeeder over 12 years
    what if there might be additional text box which name happens to be fingering other than datatexrboc? will that count all text hides including one we don't need to count?
  • B. Clay Shannon-B. Crow Raven
    B. Clay Shannon-B. Crow Raven about 9 years
    Don't you mean "foreach (TextBox tb in allTextBoxes)" for the loopiness?
  • kiltek
    kiltek almost 9 years
    Seems like the most elegant solution, but i get the error: "TControl ---> The type or namespace name 'TControl' could not be found (are you missing a using directive or an assembly reference?) ". I searched MSDN, but didnt find that class. What to do?
  • abatishchev
    abatishchev almost 9 years
    @kiltek: this is the generic parameter declared as where TControl : System.Web.Ui.Control iirc.
  • TEK
    TEK almost 9 years
    I'm getting the error "Constraints are not allowed on non-generic declarations" (.net 4.0)
  • abatishchev
    abatishchev almost 9 years
    @TEK: Right! Don't know how I missed it and nobody noticed for so long time. Fixed. Thanks!
  • TEK
    TEK almost 9 years
    @abatishchev Wow. That has to be the fastest edit of all time. Thank you! (Ignore my previous comment, I am dumb).
  • abatishchev
    abatishchev almost 9 years
    @TEK: Yea, me is getting this error, too. And I'm applied the fix, please check it out. I'm just was digging into my very old code to figure out how this code being copy-pasted was working before. Hm. weird. Anyway, now should work. Let me know if it doesn't, please.
  • TEK
    TEK almost 9 years
    @abatishchev In it's current state, it works great! Thank you kindly for the extremely rapid response to a 4+ year old post. This has saved me having to do it the old dumb way.
  • B. Clay Shannon-B. Crow Raven
    B. Clay Shannon-B. Crow Raven about 8 years
    Oddly enough, this works dandy except for a combobox that is populated with string values; in that case, the loop to set its SelectedIndex to -1 doesn't work. I have to set it explicitly after the loop for it to work. Why this would be, I don't know, but here is my code: var allComboBoxes = this.GetChildControls<ComboBox>(); foreach (ComboBox cmbx in allComboBoxes) { cmbx.SelectedIndex = -1; } comboBoxDaysOfMonth.SelectedIndex = -1;
  • B. Clay Shannon-B. Crow Raven
    B. Clay Shannon-B. Crow Raven about 8 years
    On third thought, this is happening to all the controls that are not directly on the form (those on a Panel or a Groupbox); I think that's probably the real issue/the crux of the biscuit.
  • n00dles
    n00dles almost 7 years
    I don't get how this gets ALL textboxes. For me, it only gets textboxes that are direct children of the form/given control. You still need to loop through each control with this solution, right?
  • abatishchev
    abatishchev almost 7 years
    @n00dles: the method calls itself recursively on all children of given type. Another option would be rewrite in and remove OfType<T>. So just return all children aka flatten the hierarchy. Then call OfType<T> to filter by given type.
  • n00dles
    n00dles almost 7 years
    I noticed the recursive call. I must have done something wrong then, coz it didn't return child controls. I found another similar method (but not an extension) that worked though. I don't yet understand lambda expressions, so it's hard for me to think it through.
  • abatishchev
    abatishchev almost 7 years
    @n00dles: post an answer if you found a better (or at least a similar) solution!
  • jkulpe
    jkulpe about 4 years
    This worked for me (the top answer didn't). I put my method in a static class and had to set the method signature to " ... GetAllControls<T>(this Control control) ..." for it to work. The "this" would allow an instance of a control to call this extension method.