Loop through Textboxes

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?

Answers


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 = ...;
}

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;   
}

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 :)


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;
}

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
        }

If you want to do without 'foreach' (If you have specific boxes to adjust/address)

int numControls = Page.Form.Controls.Count;

    for (int i = 0; i < numControls; i++)
    {
        if (Page.Form.Controls[i] is TextBox)
        {
            TextBox currBox = Page.Form.Controls[i] as TextBox;
            currbox.Text = currbox.TabIndex.ToString();
        }
    }

        //THE EASY WAY! Always post easy solutions. It's the best way.
        //This code is used to loop through all textboxes on a form for data validation. 
        //If an empty textbox is found, Set the error provider for the appropriate textbox.
        foreach (var control in Controls)
        {
            if (control is TextBox)
            {
                //Box the control into a textbox. Not really needed, but do it anyway
                var textbox = (TextBox)control;

                if (String.IsNullOrWhiteSpace(textbox.Text))
                {
                    //Set the errorProvider for data validation
                    errorProvider1.SetError(textbox, "Data Required!");
                    textbox.Text = String.Empty; //Clear out the whitespace if necessary
                    //blnError = true;
                }
            }
        }

You can simply do this mate...

foreach (TextBox txt in this.Panel.Controls.OfType<TextBox>())
            {
                txt.Text="some value you assign";
            }

If your text boxes are on the form directly and not on a Panel then you can replace this.Panel.Controls with this.Controls. That should be short and clear enough for you.


After the InitialiseComponents() call, add the textboxes to a collection member variable on the form. You can then iterate through them in order later on.


You can create a Dictionary of TextBox, int like the following

Dictionary<TextBox, int> textBoxes = new Dictionary<TextBox, int>();

foreach (TextBox control in Controls.OfType<TextBox>())
    textBoxes[control] = Convert.ToInt32(control.Name.Substring(11));

Now.. to loop through them..

foreach (var item in textBoxes.Select(p => new { textBox = p.Key, no = p.Value}))
     item.textBox.Text = item.no.ToString(); // whatever you want...

Good luck!


Since you already know the name of control, therefore you can search the control by its name.

See Get a Windows Forms control by name in C#


Other answers just not cutting it for you? I found this as an answer to a similar question on SO, but I can't find the thread now. It recursively loops through ALL controls of a given type which are located within a control. So includes children of children of children of... etc. My example changes the ForeColor of each TextBox to Hot Pink!

public IEnumerable<Control> GetAllControlsOfType(Control control, Type type)
{
    var controls = control.Controls.Cast<Control>();

    return controls.SelectMany(ctrl => GetAllControlsOfType(ctrl, type))
                              .Concat(controls)
                              .Where(c => c.GetType() == type);
}

Implementation:

IEnumerable<Control> allTxtBxs = GetAllControlsOfType(this, typeof(TextBox));
foreach (TextBox txtBx in allTxtBxs)
{
    txtBx.ForeColor = Color.HotPink;
}

Quite similar to abatishchev's answer(which, for me, only returned first-level child controls), but different enough to merit it's own answer I think.


Need Your Help

Understanding virtual address and virtual address space

architecture operating-system virtual memory-address virtual-address-space

I read that , "When a program executes an instruction like : MOV REG,1000 , it does so to copy the contents of the memory address 1000 to REG. Address can be generated using indexing,base registers,

Angular 2, set default value to select option

javascript angular angular2-forms

I try to add a default value to an option. It will be like a kind of placeholder and I use this method to do it.