it-swarm.com.ru

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

У меня есть приложение 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, я должен пройти через основные элементы управления (панели), а затем просмотреть элементы управления на панелях. Это начинает усложняться.

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

15
Taryn

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

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

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

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

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

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-решение :)

4
Christian

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

    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
Zath .

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

int i = 0;
foreach (Control contrl in this.Controls) {
    if (contrl.Name == ("DateTextBox" + i.ToString())) {
        contrl.Text = "requiredtexttobeset";
    }
    i = i + 1;
}
2
Ismail

Если вы хотите обойтись без '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();
        }
    }
1
Mark

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

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

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

1
indago
        //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
puffgroovy

После вызова InitialiseComponents() добавьте текстовые поля в переменную-член коллекции на форме. Затем вы можете просмотреть их по порядку позже.

0
Neil Barnwell

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

См. Получить элемент управления Windows Forms по имени в C #

0
Ramesh Soni

Другие ответы просто не режут для вас?
Я нашел это как ответ на аналогичный вопрос о 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;
}

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

0
n00dles

Вы можете создать 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...

Удачи!

0
Homam