2011-02-01 21 views
11

Tengo una aplicación de winforms que tiene 37 cuadros de texto en la pantalla. Cada una está numerada secuencialmente:Bucle a través de cuadros de texto

DateTextBox0 
DateTextBox1 ... 
DateTextBox37 

Estoy tratando de iterar a través de los cuadros de texto y asignar un valor a cada uno:

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

Aclaro que estos cuadros de texto aparecen en paneles separados (37 de ellos). Entonces, para que pueda recorrer usando un foreach, tengo que pasar por los controles primarios (los paneles), luego recorrer los controles en los paneles. Comienza a complicarse.

¿Alguna sugerencia sobre cómo puedo asignar este valor al cuadro de texto?

+0

¿Desea asignar 'TextBox.Name' o' TextBox.Text'? – abatishchev

+0

Quiero asignar Textbox.Text al cuadro de texto con el nombre = DateTextBox (daysoffset + i). – Taryn

Respuesta

32

Para obtener todos los controles y sub-controles de forma recursiva del tipo especificado, usar este método de extensión:

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

uso:

var allTextBoxes = this.GetChildControls<TextBox>(); 
foreach (TextBox tb in allTextBoxes) 
{ 
    tb.Text = ...; 
} 
+6

+1 - ese es casi exactamente el código que estaba a punto de publicar. –

+0

¿No quiere decir "foreach (TextBox tb en allTextBoxes)" para el bucle? –

+0

@ B.ClayShannon: Correcto, gracias, actualizado. – abatishchev

4

Puede recorrer los cuadros de texto en su forma de una manera bastante simple:

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

Editar: cambiar de acuerdo a las nuevas exigencias. No es tan elegante como el LINQ-solución, por supuesto :)

+0

Eso omitirá los controles que no se encuentran directamente en el formulario (como en un panel, página con pestañas o similar). –

+0

Sé que puedo recorrer los controles pero esta pantalla contiene 37 paneles con DateTextBoxes y otro control. Entonces, para poder obtener los datos, tengo que pasar por los controles del panel y luego los controles en el panel para obtener una matriz. ¿Hay alguna manera de hacerlo sin usar una matriz? ¿Simplemente asigna a DateTextBoxes los datos que necesita? – Taryn

+0

@bluefeet: consulte mi respuesta para encontrar cómo recorrer los controles anidados – abatishchev

0

Después de la llamada InitialiseComponents(), agregue los cuadros de texto a una variable de miembro de colección en el formulario. A continuación, puede iterar a través de ellos en orden más adelante.

2

Examine los controles dentro del formulario y verifique el nombre del control si coincide y luego establezca la propiedad Texto como lo requiera.

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

Se puede crear un Dictionary de TextBox, int como la siguiente

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

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

Ahora .. bucle a través de ellos ..

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

Buena suerte!

6

Puede recorrer todos los controles en el formulario preguntando uno por uno si es un "Cuadro de texto" y luego devolver la Lista completa de ellos.

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

¿qué pasa si puede haber un cuadro de texto adicional cuyo nombre sea fingering distinto de datatexrboc? ¿contará eso todas las pieles de texto incluyendo una que no necesitamos contar? – HelpNeeder

1

Si desea prescindir 'foreach' (Si tiene cajas específicas para ajustar/dirección)

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

Desde este post parece resucitar a sí mismo de vez en cuando y desde las soluciones anteriores no encuentran controles dentro de los controles, como en un cuadro de grupo, esto los encontrará.Sólo tiene que añadir el tipo de control:

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

Y es su uso:

 var listBoxes = GetAllControls<ListBox>(this); 
     foreach (ListBox lst in listBoxes) 
     { 
      //Do Something 
     } 
1

Usted puede simplemente hacer esto compañero ...

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

Si los cuadros de texto están en forma directa e no en un Panel, entonces puede reemplazar this.Panel.Controls con this.Controls. Eso debería ser lo suficientemente breve y claro para ti.

0

Otras respuestas simplemente no lo hacen por usted?
Encontré esto como una respuesta a una pregunta similar en SO, pero ahora no puedo encontrar el hilo. Se repite de manera repetitiva a través de TODOS los controles de un dado type que están ubicados dentro de un control. Entonces incluye hijos de hijos de hijos de ... etc. ¡Mi ejemplo cambia el ForeColor de cada TextBox a la rosa fuerte!

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

Implementación:

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

bastante similar a abatishchev's answer (que, para mí, sólo volvió primer nivel controles secundarios), pero lo suficientemente diferentes como para merecer su propia respuesta que pienso.

Cuestiones relacionadas