2011-02-01 121 views
11

我有一个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,我必须遍历主要控件(面板),然后遍历面板上的控件。它开始变得复杂。

有关如何将此值分配给文本框的任何建议?

+0

是否要分配“TextBox.Name”或“TextBox.Text”? – abatishchev 2011-02-01 13:29:41

+0

我想将Textbox.Text分配给名称为DateTextBox(daysoffset + i)的文本框。 – Taryn 2011-02-01 13:40:33

回答

32

要获得所有的控制和子控制递归指定类型的,使用这个扩展的方法,:

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

可以遍历在一个相当简单的方式在表单中的文本框:

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的解决方案,当然:)

+0

这将错过任何不直接位于表单上的控件(例如面板,标签页或类似内容)。 – 2011-02-01 13:27:23

+0

我知道我可以通过控件循环,但此屏幕包含与DateTextBoxes以及另一个控件的37个面板。因此,为了让我获得数据,我必须通过面板控件循环,然后通过面板中的控件来获取数组。有没有办法让我做到这一点,而不使用数组?只需将DateTextBoxes分配给它所需的数据? – Taryn 2011-02-01 13:29:26

0

调用InitialiseComponents()后,将文本框添加到表单上的集合成员变量。然后你可以按顺序遍历它们。

2

遍历表单中的控件并检查控件的名称(如果匹配),然后根据需要设置Text属性。

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

你可以像下面

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

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

现在..通过他们向循环创建TextBoxDictionaryint ..

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

祝你好运!

6

如果是“文本框”,则可以循环显示表单中所有控件,并返回它们的完整列表。

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

如果你想不“的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
 //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; 
       } 
      } 
     } 
2

由于这个职位似乎是从一次复活自己的时间和自上述解决方案在控件内部找不到控件,例如在groupbox中,这会找到它们。只需添加您的控制类型:

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

你可以简单地这样做伴侣......

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

如果你的文本框的形式直接与不在面板上,那么您可以用this.Controls替换this.Panel.Controls。对于你来说,这应该很简短明了。

0

其他答案只是不为你削减它?
我发现这是对类似问题的回答,但我现在找不到线索。它通过位于control内的给定type的所有控件递归循环。所以包括...的孩子的孩子等。我的例子将TextBoxForeColor更改为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); 
} 

实现:

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

神似abatishchev's answer(其中,,只返回一级子控件),但也足够不同,值得它自己的答案,我想。