Loop through Textboxes

2019-01-01 09:19发布

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?

12条回答
只若初见
2楼-- · 2019-01-01 09:32

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

查看更多
墨雨无痕
3楼-- · 2019-01-01 09:35

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.

查看更多
低头抚发
4楼-- · 2019-01-01 09:40

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();
        }
    }
查看更多
人气声优
5楼-- · 2019-01-01 09:40

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.

查看更多
时光乱了年华
6楼-- · 2019-01-01 09:42

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 = ...;
}
查看更多
呛了眼睛熬了心
7楼-- · 2019-01-01 09:42

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
        }
查看更多
登录 后发表回答