Цикл через текстовые поля - PullRequest
       25

Цикл через текстовые поля

15 голосов
/ 01 февраля 2011

У меня есть приложение winforms, которое имеет 37 текстовых полей на экране.Каждый из них последовательно пронумерован:

DateTextBox0
DateTextBox1 ...
DateTextBox37

Я пытаюсь перебрать текстовые поля и назначить каждому значение:

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

Позвольте мне уточнить, что эти текстовые поля появляются на отдельныхпанели (37 из них).Таким образом, для того чтобы я мог выполнить цикл с помощью foreach, я должен пройти через основные элементы управления (панели), а затем просмотреть элементы управления на панелях.Это начинает усложняться.

Есть предложения о том, как я могу присвоить это значение текстовому полю?

Ответы [ 12 ]

37 голосов
/ 01 февраля 2011

Чтобы рекурсивно получить все элементы управления и подэлементы управления указанного типа, используйте этот метод расширения:

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

использование:

var allTextBoxes = this.GetChildControls<TextBox>();
foreach (TextBox tb in allTextBoxes)
{
    tb.Text = ...;
}
6 голосов
/ 01 февраля 2011

Вы могли бы зациклить все элементы управления в форме, спрашивая один за другим, является ли это «Текстовым полем», чтобы вернуть полный их список.

public List GetTextBoxes(){   
    var textBoxes = new List();   
        foreach (Control c in Controls){   
            if(c is TextBox){   
                textBoxes.add(c);   
        }   
    }   
return textBoxes;   
}
4 голосов
/ 01 февраля 2011

Вы можете циклически проходить по текстовым полям в своей форме довольно простым способом:

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

Редактировать: Изменено в соответствии с новыми требованиями.Конечно, не так элегантно, как решение LINQ:)

2 голосов
/ 07 декабря 2016

Поскольку этот пост время от времени возрождается, а вышеприведенные решения не находят элементы управления внутри элементов управления, например в групповом окне, они найдут их.Просто добавьте свой тип управления:

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

И он используется:

        var listBoxes = GetAllControls<ListBox>(this);
        foreach (ListBox lst in listBoxes)
        {
            //Do Something
        }
2 голосов
/ 01 февраля 2011

Перебирайте элементы управления в форме и проверяйте имя элемента управления, если оно соответствует, затем устанавливайте свойство Text, как вам требуется.

int i = 0;
foreach (Control contrl in this.Controls) {
    if (contrl.Name == ("DateTextBox" + i.ToString())) {
        contrl.Text = "requiredtexttobeset";
    }
    i = i + 1;
}
1 голос
/ 06 февраля 2017

Вы можете просто сделать это, приятель ...

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

Если ваши текстовые поля находятся непосредственно в форме, а не на Panel, вы можете заменить this.Panel.Controls на this.Controls. Это должно быть коротким и достаточно ясным для вас.

1 голос
/ 26 февраля 2015
        //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;
                }
            }
        }
1 голос
/ 01 октября 2011

Если вы хотите обойтись без 'foreach' (если у вас есть конкретные поля для настройки / адреса)

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();
        }
    }
0 голосов
/ 02 июля 2017

Другие ответы просто не подрезали?
Я нашел это как ответ на аналогичный вопрос о SO, но я не могу найти ветку сейчас. Он рекурсивно проходит по ВСЕМ элементам управления данного type, которые находятся в пределах control. Так что включает детей детей детей ... и т. Д. Мой пример меняет ForeColor каждого TextBox на ярко-розовый!

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

Реализация:

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

Очень похоже на ответ Абатищева (который, для меня , только вернул дочерний элемент управления первого уровня), но достаточно отличается, чтобы заслужить свой собственный ответ. I думаю.

0 голосов
/ 01 февраля 2011

Вы можете создать Dictionary из TextBox, int, как показано ниже

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

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

Теперь .. чтобы пройти через них ..

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

Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...