Passa attraverso le caselle di testo

Ho un’app winforms che ha 37 caselle di testo sullo schermo. Ognuno è numerato in sequenza:

DateTextBox0 DateTextBox1 ... DateTextBox37 

Sto cercando di scorrere le caselle di testo e assegnare un valore a ciascuna:

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

Permettetemi di chiarire che queste caselle di testo compaiono su pannelli separati (37 di loro). Quindi, per consentirmi di eseguire il ciclo di accesso utilizzando un foreach, devo scorrere i controlli primari (i pannelli), quindi eseguire il ciclo dei controlli sui pannelli. Inizia a complicarsi.

Qualche suggerimento su come posso assegnare questo valore alla casella di testo?

Per ottenere ricorsivamente tutti i controlli e sottocontrolli del tipo specificato, utilizzare questo metodo di estensione:

 public static IEnumerable GetChildControls(this Control control) where TControl : Control { var children = (control.Controls != null) ? control.Controls.OfType() : Enumerable.Empty(); return children.SelectMany(c => GetChildControls(c)).Concat(children); } 

utilizzo:

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

È ansible eseguire il ciclo di tutti i controlli nel modulo chiedendo uno per uno se è una “casella di testo” e restituire l’elenco completo di essi.

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

Puoi scorrere le caselle di testo nel tuo modulo in un modo abbastanza semplice:

 Func> SearchTextBoxes = null; SearchTextBoxes = coll => { List textBoxes = new List(); 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); 

Modifica: modificato in base ai nuovi requisiti. Non proprio elegante come la soluzione LINQ, ovviamente 🙂

Scorrere i controlli all’interno del modulo e controllare il nome del controllo se abbinato, quindi impostare la proprietà Text come richiesto.

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

Poiché questo post sembra risorgere di volta in volta e poiché le soluzioni sopra non trovano controlli all’interno dei controlli, come in una groupbox, questo li troverà. Basta aggiungere il tuo tipo di controllo:

  public static IList GetAllControls(Control control) where T : Control { var lst = new List(); foreach (Control item in control.Controls) { var ctr = item as T; if (ctr != null) lst.Add(ctr); else lst.AddRange(GetAllControls(item)); } return lst; } 

Ed è:

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

Se vuoi fare a meno di ‘foreach’ (se hai caselle specifiche da regolare / indirizzare)

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

Puoi semplicemente fare questo compagno …

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

Se le caselle di testo sono nel modulo direttamente e non in un pannello, puoi sostituire this.Panel.Controls con this.Controls . Questo dovrebbe essere breve e abbastanza chiaro per te.

Dopo la chiamata InitialiseComponents() , aggiungere le caselle di testo a una variabile membro della raccolta nel modulo. È quindi ansible scorrere tra di loro in ordine in un secondo momento.

Puoi creare un Dictionary di TextBox , int come il seguente

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

Ora .. per scorrere attraverso loro ..

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

In bocca al lupo!

Dal momento che conosci già il nome del controllo, puoi quindi cercare il controllo per nome.

Vedi Ottieni un controllo Windows Form per nome in C #

Altre risposte semplicemente non tagliando per te?
Ho trovato questo come risposta a una domanda simile su SO, ma non riesco a trovare il thread ora. In modo ricorsivo scorre tutti i controlli di un determinato type che si trovano all’interno di un control . Quindi include bambini di bambini di bambini di … ecc. Il mio esempio cambia il ForeColor di ogni TextBox in Hot Pink!

 public IEnumerable GetAllControlsOfType(Control control, Type type) { var controls = control.Controls.Cast(); return controls.SelectMany(ctrl => GetAllControlsOfType(ctrl, type)) .Concat(controls) .Where(c => c.GetType() == type); } 

Implementazione:

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

Abbastanza simile alla risposta di abatishchev (che, per me , ha restituito solo controlli secondari di primo livello ), ma abbastanza differente da meritare la propria risposta, penso.