Let's say I have 30 controls, all lbls, all called "lblA" with a number after.
I also have 30 textboxes, same thing - called "txtB" with a number after.
How exactly would I formated this.
for (i = 1; i < this.controls.count;i++)
{
if ("lblA"+i=null)
{
break;
}
string A = string A + ("lblA" + i).Text
string B = string B + ("txtB" + i).Text
}
I've tried a few different things like calling the object with this.controls[i] but it's not exactly what I want. What I am doing is I have a lot of labels and text boxes in a form that are added at run time. I need to loop through the form to get them all. I'm writting it as a for each with quite a few ifs, but I'm curious if there's a dynamic way to do it.
I've looked for about 1-1:30 hours online and found nothing close to, thanks for the help all.
var labels = new Dictionary<int, string>();
for (i = 1; i < this.controls.count;i++)
{
var label = FindControl("lblA" + i) as Label;
if (label == null)
{
break;
}
labels.Add(i, label.Text);
}
What you want to use is the FindControl method.
Example in VB:
Dim txtMileage As TextBox = CType(cphLeft.FindControl("txtMileage" & iControlCountDays.ToString()), TextBox)
Maybe this will solve what you're after:
void GetSpecialControls() {
const string TXT_B = "txtB";
const string LBL_A = "lblA";
List<TextBox> textBoxList = new List<TextBox>();
List<Label> labelList = new List<Label>();
foreach (Control ctrl in this.Controls) {
Label lbl = ctrl as Label;
if (lbl != null) {
if (lbl.Text.IndexOf(LBL_A) == 0) {
labelList.Add(lbl);
}
} else {
TextBox txt = ctrl as TextBox;
if (txt != null) {
if (txt.Text.IndexOf(TXT_B) == 0) {
textBoxList.Add(txt);
}
}
}
}
Console.WriteLine("Found {0} TextBox Controls.", textBoxList.Count);
Console.WriteLine("Found {0} Label Controls.", labelList.Count);
}
Related
I am trying to create a TextBox based on the selection on ComboBox dynamically based on the following steps:
First step (Select a source from ComboBox):
Second step (Textbox should appear based on ComboBox.SelectedValue):
Last step (A new ComboBox should appear below):
I have created a createTextBox function using the following code:
public void createTextBox(int numPassenger)
{
TextBox[] passengerBoxes = new TextBox[numPassenger];
for (int u = 0; u < passengerBoxes.Count(); u++)
{
passengerBoxes[u] = new TextBox();
}
int i = 0;
foreach (TextBox txt in passengerBoxes)
{
string name = "passenger" + i.ToString();
txt.Name = name;
txt.Text = name;
txt.Location = new Point(244, 32 + (i * 28));
txt.Visible = true;
this.Controls.Add(txt);
i++;
}
}
Is there a way that I can modify my current function to adapt to the mentioned steps? Additionally, how can I find the dynamically created TextBox?
You can try the following code:
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
createTextBox(sender as ComboBox);
}
private void createTextBox(ComboBox cmb)
{
TextBox passengerBoxes = new TextBox();
string name = cmb.Text;
if (Controls.Find(name, true).Length == 0)
{
passengerBoxes.Name = name;
passengerBoxes.Text = name;
int textBoxCount = GetTextBoxCount();
passengerBoxes.Location = new Point(244, 32 + (textBoxCount * 28));
passengerBoxes.Visible = true;
this.Controls.Add(passengerBoxes);
if (cmb.Items.Count != 1)//last item remaining then we should not create new combo box
{
ComboBox newCombo = new ComboBox
{
Location = new Point(cmb.Location.X, 32 + ((textBoxCount + 1) * 28))
};
foreach (string str in cmb.Items)
if (cmb.Text != str)
newCombo.Items.Add(str);
newCombo.SelectedIndexChanged += comboBox1_SelectedIndexChanged;
this.Controls.Add(newCombo);
}
}
else
MessageBox.Show("Textbox Already for the selected source " + name);
}
private int GetTextBoxCount()
{
int i = 0;
foreach (Control ctl in this.Controls)
{
if (ctl is TextBox) i++;
}
return i;
}
I want to get values from a selected row of DataGridView and assign them into a few different
controls on a Form when a control's name match a column's name (there is TextBox, ComboBox and NumericUpDown).
This is how I am populating the controls currently:
Form myForm = new Form();
if (comboBoxTable.Text == "Client")
{
myForm = new EditClientDataWindow();
}
else if (comboBoxTable.Text == "Agency")
{
myForm = new EditAgencyDataWindow();
}
else if (comboBoxTable.Text == "Medicine")
{
myForm = new EditMedicineDataWindow();
}
string val;
foreach (Control c in myForm.Controls)
{
for (int i = 0; i < dataGridViewMDB.ColumnCount; i++)
{
val = dataGridViewMDB.SelectedRows[0].Cells[i].Value.ToString();
if (dataGridViewMDB.Columns[i].Name.ToString() ==
c.Name.ToLower().Replace(c.GetType().ToString().ToLower().Replace("system.windows.forms.", ""), ""))
{
if (c is NumericUpDown)
(c as NumericUpDown).Value = Convert.ToInt32(val);
else
c.Text = val;
}
}
}
With the exception of NumericUpDown, the other types of controls are correctly populated. For the NumericUpDown, I only ever get the default -1 value. I've also tried to use decimal.Parse() and Convert.ToDecimal() instead of Convert.ToInt32(), but there is no change in the result.
The range of NumericUpDown had been set to -1 and 999.
It's not an answer, but a way to reduce a space for error searching, because it's a lot of things going on under the hood.
Can you please change your code to
foreach (Control c in myForm.Controls)
{
if (c is NumericUpDown)
(c as NumericUpDown).Value = 12;
else
c.Text = "12";
}
After this all controls should be set to 12. Can you please test it and get back with the observations.
I'm making a windowsform with dynamically created textboxes as u see in the method.
public void createPassengerBoxes(int numPassenger)
{
TextBox[] passengerBoxes = new TextBox[numPassenger];
for (int u = 0; u < passengerBoxes.Count(); u++)
{
passengerBoxes[u] = new TextBox();
}
int i = 0;
foreach (TextBox txt in passengerBoxes)
{
string name = "passenger" + i.ToString();
txt.Name = name;
txt.Text = name;
txt.Location = new Point(244, 32 + (i * 28));
txt.Visible = true;
this.Controls.Add(txt);
i++;
}
}
}
How do I access the text from the boxes?
While I'm not sure at what point, or based on what action, you'd like to fetch the data, here's very generic method:
private String[] GetTextBoxStrings()
{
List<String> list = new List<String>();
foreach (Control c in this.Controls)
{
if (c is TextBox)
list.Add(((TextBox)c).Text);
}
return list.ToArray();
}
Move your textbox declaration outside of the function. This makes it accessible from other functions within the class:
class MyFormsClass
{
// declare textboxes at class level
TextBox[] passengerBoxes;
public void createPassengerBoxes(int numPassenger)
{
passengerBoxes = new TextBox[numPassenger];
...
}
public void OnButtonClick(...)
{
if (passengernBoxes != null)
{
foreach (TextBox txt in passengerBoxes)
{
// do something with textboxes
}
}
}
...
}
You could also use Lambda:
var strings = Controls.OfType<TextBox>()
.Select(c => c.Text)
.ToList();
this only work if ou have no nested controls - e.g. a pannel or a group that holds some textBoxes
I want to access multiple textbox name textbox1,textbox2,textbox3, etc.. by loop not by individual name. For that reason I created one function which create this var names.
public string[] nameCre(string cntrlName, int size)
{
string[] t = new string[size];
for (int i = 0; i < size; i++)
{
t[i] = cntrlName.ToString() + (i + 1);
}
return t;
}
for nameCre("Textbox",5); So this,function successfully returning me TextBox1, TextBox2 ... TextBox5.
But when I am trying to convert this string to TextBox control by
string[] t = new string[50];
t= nameCre("TextBox",5);
foreach (string s in t)
{
((TextBox) s).Text = "";
}
it giving me error :
Cannot convert type 'string' to 'System.Windows.Forms.TextBox'....
How can I accomplish this job?
var t = nameCre("TextBox",5);
foreach (var s in t)
{
var textBox = new TextBox {Name = s, Text = ""};
}
string[] t= new string[50];
t= nameCre("TextBox",5);
foreach (string s in t){
TextBox tb = (TextBox)this.Controls.FindControl(s);
tb.Text = "";
}
if you have many text boxes
foreach (Control c in this.Controls)
{
if (c.GetType().ToString() == "System.Windows.Form.Textbox")
{
c.Text = "";
}
}
Perhaps you need this -
string[] t = new string[50];
t = nameCre("TextBox", 5);
foreach (string s in t)
{
if (!string.IsNullOrEmpty(s))
{
Control ctrl = this.Controls.Find(s, true).FirstOrDefault();
if (ctrl != null && ctrl is TextBox)
{
TextBox tb = ctrl as TextBox;
tb.Text = "";
}
}
}
This post is quite old, anyway I think I can give you (or anyone else with a problem like that) an answer:
I think using an Array (or List) of TextBoxs would be the best solution for doing that:
// using an Array:
TextBox[] textBox = new TextBox[5];
textBox[0] = new TextBox() { Location = new Point(), /* etc */};
// or
textBox[0] = TextBox0; // if you already have a TextBox named TextBox0
// loop it:
for (int i = 0; i < textBox.Length; i++)
{
textBox[i].Text = "";
}
// using a List: (you need to reference System.Collections.Generic)
List<TextBox> textBox = new List<TextBox>();
textBox.Add(new TextBox() { Name = "", /* etc */});
// or
textBox.Add(TextBox0); // if you already have a TextBox named TextBox0
// loop it:
for (int i = 0; i < textBox.Count; i++)
{
textBox[i].Text = "";
}
I hope this helps :)
I have a page that holds 5 texboxes each name similar but with a numerial suffix. Example:
tbNumber1, tbNumber2, tbNumber3 and so on.
The reason it's like that is because those textboxes are generated dynamically based on some parameter. I never know how many textboxes will be need for a particular record.
How can I loop trough the text contents of these texboxes?
MY first instinct was to do something like the following, but that obviously does't work :)
for (int i = 0; i <= 3; i++)
{
string foo = tbNumber+i.Text;
//Do stuff
}
Wahts the best way to go trough each of these textboxes?
Thanks!!!
You might be able to do something like this:
for( int i = 0; i < upperLimit; i++ )
{
TextBox control = Page.FindControl("tbNumber" + i) as TextBox;
if( control != null ) {
// do what you need to do here
string foo = control.Text;
}
}
Possibly try something like
foreach(Control control in Page.Controls)
{
//Do stuff
}
If you're generating them dynamically, put them in a List<TextBox> as you generate them:
// in the Page_Load or whereever you generate the textboxes to begin
var boxes = new List<TextBox>();
for (int i = 0; i < numRecords /* number of boxes */; i++) {
var newBox = new TextBox();
// set properties here
boxes.Add(newBox);
this.Controls.Add(newBox);
}
Now you can loop through the textboxes without using crufty string techniques:
foreach (var box in boxes) {
string foo = box.Text;
// stuff
}
What you need is a recursive FindControl like function. Try something like this:
for (int i=0; i<3; i++)
{
Control ctl = FindControlRecursive(Page.Controls, "tbNumber", i.ToString());
if (ctl != null)
{
if (ctl is TextBox)
{
TextBoxControl tbc = (TextBox)ctl;
// Do Something with the control here
}
}
}
private static Control FindControlRecursive(Control Root, string PrefixId, string PostFix)
{
if (Root.ID.StartsWith(PrefixId) && Root.ID.EndsWith(PostFix))
return Root;
foreach (Control Ctl in Root.Controls)
{
Control FoundCtl = FindControlRecursive(Ctl, PrefixId, PostFix);
if (FoundCtl != null)
return FoundCtl;
}
return null;
}
If you're using a CheckBoxList control you should be able to loop through each checkbox in the control.
foreach(var checkbox in checkboxlistcontrol)
{
string name = checkbox.Text;
}
If you're not using a CheckboxList control, you might want to consider using one as an option.