J'ai une application Winforms qui a 37 zones de texte à l'écran. Chacun est numéroté séquentiellement:
DateTextBox0
DateTextBox1 ...
DateTextBox37
J'essaie de parcourir les zones de texte et d'attribuer une valeur à chacune d'entre elles:
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();
}
Permettez-moi de préciser que ces zones de texte apparaissent sur des panneaux distincts (37 d'entre eux). Donc, pour pouvoir utiliser une foreach en boucle, je dois parcourir les contrôles principaux (les panneaux), puis les contrôles des panneaux. Ça commence à se compliquer.
Des suggestions sur la façon dont je peux affecter cette valeur à la zone de texte?
Pour obtenir tous les contrôles et sous-contrôles de manière récursive du type spécifié, utilisez cette méthode d'extension:
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);
}
usage:
var allTextBoxes = this.GetChildControls<TextBox>();
foreach (TextBox tb in allTextBoxes)
{
tb.Text = ...;
}
Vous pourriez boucler toutes les commandes du formulaire en demandant une à une s'il s'agit d'une "zone de texte" et en renvoyer la liste complète.
public List GetTextBoxes(){
var textBoxes = new List();
foreach (Control c in Controls){
if(c is TextBox){
textBoxes.add(c);
}
}
return textBoxes;
}
Vous pouvez parcourir les zones de texte de votre formulaire d’une manière assez 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);
Modifier: modifié en fonction des nouvelles exigences. Pas aussi élégant que la solution LINQ, bien sûr :)
Puisque ce message semble se ressusciter de temps en temps et que les solutions ci-dessus ne trouvent pas de contrôles à l'intérieur de contrôles, comme dans une zone de groupe, ils les trouveront. Ajoutez simplement votre type de contrôle:
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;
}
Et c'est usage:
var listBoxes = GetAllControls<ListBox>(this);
foreach (ListBox lst in listBoxes)
{
//Do Something
}
Parcourez les contrôles du formulaire et vérifiez le nom du contrôle s'il correspond, puis définissez la propriété Text comme vous le souhaitez.
int i = 0;
foreach (Control contrl in this.Controls) {
if (contrl.Name == ("DateTextBox" + i.ToString())) {
contrl.Text = "requiredtexttobeset";
}
i = i + 1;
}
Si vous voulez vous passer de 'foreach' (si vous avez des cases spécifiques à ajuster/adresse)
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();
}
}
Vous pouvez simplement faire ce compagnon ...
foreach (TextBox txt in this.Panel.Controls.OfType<TextBox>())
{
txt.Text="some value you assign";
}
Si vos zones de texte se trouvent directement sur le formulaire et non sur un panneau, vous pouvez remplacer this.Panel.Controls
par this.Controls
. Cela devrait être assez court et clair pour vous.
//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;
}
}
}
Après l'appel InitialiseComponents()
, ajoutez les zones de texte à une variable de membre de collection du formulaire. Vous pouvez ensuite les parcourir dans l'ordre plus tard.
Puisque vous connaissez déjà le nom du contrôle, vous pouvez donc rechercher le contrôle par son nom.
D’autres réponses ne vous suffisent pas?
J'ai trouvé cela comme une réponse à une question similaire sur SO, mais je ne trouve pas le fil maintenant. Il parcourt de manière récursive TOUS les contrôles d'une type
donnée situés dans une control
. Cela inclut donc les enfants d’enfants d’enfants de ... etc. Mon exemple change la ForeColor
de chaque TextBox
en 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);
}
La mise en oeuvre:
IEnumerable<Control> allTxtBxs = GetAllControlsOfType(this, typeof(TextBox));
foreach (TextBox txtBx in allTxtBxs)
{
txtBx.ForeColor = Color.HotPink;
}
Assez similaire à la réponse de abatishchev (qui, pour moi , ne retourne que de premier niveau contrôles enfants), mais suffisamment différente pour mériter sa propre réponse, je pense.
Vous pouvez créer une Dictionary
de TextBox
, int
comme suit
Dictionary<TextBox, int> textBoxes = new Dictionary<TextBox, int>();
foreach (TextBox control in Controls.OfType<TextBox>())
textBoxes[control] = Convert.ToInt32(control.Name.Substring(11));
Maintenant .. pour les parcourir en boucle ..
foreach (var item in textBoxes.Select(p => new { textBox = p.Key, no = p.Value}))
item.textBox.Text = item.no.ToString(); // whatever you want...
Bonne chance!