Count the number of controls - C# with the certain names? - c#

C# - 2.0
I am trying to figure out on how to do a loop on a list of controls with certain names: "txtTesting[i]"
txtTesting1
txtTesting2
txtTesting3 ...
txtTesting13
With the code I have a total of 13. But this can change as time goes by. So I am looking to get the data from the textboxes that have data in them. I just can not seem to figure out a way to do a count of the controls. I have tried this...
for (int i = 1; i < 13; i++)
{
if (txtTesting[i].text != "")
{
//
}
}
I am also getting this error...
Error 51 The name 'txtTesting' does not exist in the current context
Unless I am missing something here.
System.Web.UI.WebControls.TextBox

Assuming this is a System.Windows.Forms application, you should be able to go through all your controls on the form and then select the ones that are TextBox as follows:
foreach (System.Windows.Forms.Control control in this.Controls)
{
if (control is System.Windows.Forms.TextBox)
{
if (((System.Windows.Forms.TextBox)control).Text != "")
{
// Do something
}
}
}
For an asp.net application this would be very similar:
foreach (System.Web.UI.Control control in this.Controls)
{
if (control is System.Web.UI.WebControls.TextBox)
{
if ((System.Web.UI.WebControls.TextBox)control).Text != "")
{
// Do something
}
}
}

txtTesting looks like an array. does it have a Length property?
for (int i = 1; i < txtTesting.Length; i++)
if it's a type List<T> than maybe it has a Count property
for (int i = 1; i < txtTesting.Count; i++)
If you don't already have an array, you can initialize one in your presumed Form's constructor
List<WhateverTypeTxtTestingIs> txtTesting = new List<WhateverTypeTxtTestingIs>();
txtTesting.Add(txtTesting1);
txtTesting.Add(txtTesting2);
...

The most efficient way would be to add the controls to an array and loop over that, but you could also loop through the controls and inspect the control's Name:
foreach(Control c in this.Controls) // <-- "this" may not be appropriate - you just need to reference the containing control
{
if(c.Name.StartsWith("txtTesting")
{
///
}
}

In your constructor, after the call to InitializeComponent, stuff the text boxes in a collection.
// class-scoped variable
private List<Textbox> _boxen = new List<TextBox>();
public MyFormDerp()
{
InitializeComponent();
_boxen.Add(txtTesting1);
// etc
_boxen.Add(txtTesting13);
}
and, later on...
foreach(TextBox box in _boxen)
if (box.text != "")
{
//
}
Also, your design should make you itch.

You can use a foreach over your array:
foreach (TextBox txt in txtTesting)
{
if (txt.text != "")
{
//
}
}
Or, the array has a length property that you can use.
for (int i = 1; i < txtTesting.length; i++)
{
if (txtTesting[i].text != "")
{
//
}
}
If you don't have an array of controls, you may want to look at this answer to loop through all the controls on your form. Except the generic Dictionary isn't in C# 2, so it will look more like this:
private void button1_Click(object sender, EventArgs e)
{
ArrayList txtTesting = ArrayList();
LoopControls(controls, this.Controls);
foreach (TextBox txt in txtTesting)
{
if (txt.text != "")
{
//
}
}
}
private void LoopControls(ArrayList list, Control.ControlCollection controls)
{
foreach (Control control in controls)
{
if (control is TextBox && control.Name.StartsWith("txtTesting"))
list.Add(control);
if (control.Controls.Count > 0)
LoopControls(list, control.Controls);
}
}

Related

Variable in C# for loop

I have got many buttons in my Application Form. And I would like to check every buttons text (compare). How can I achive that ?
for (i = 1; i < 30; i++)
{
if (this.button1.Text == "Hello") //here is PROBLEM
{
//..some statement
}
}
So next time this.button1.Text must change to this.button2.Text and so on...
this.button[i].Text not working.
Buttons are not arrays. Each one is a discreet object, and a child of its container.
Ideally, you need to build a collection (array, list, whatever) of the buttons and iterate through that collection, rather than using an index variable (i).
Here's a good approach: https://stackoverflow.com/a/3426721/820068
This is a correct syntax:
foreach (Control button in this.Controls)
{
if (button.GetType() == typeof(Button) && button.Text == "Hello")
{
//..some statement
}
}
I'm quite sure that this is a windows form.
And in windows form you can iterate the controls like this.
foreach (Control c in panel.Controls)
{
string cType = c.GetType().ToString();
// check all buttons
if (cType == "System.Web.UI.WebControls.Button")
{
if(((Button)c).Text == "Hello")
{
}
}
}
So what the code does is to iterate all the controls inside a panel and check each control if it's type is a button.
Update:
As Wesley said, much better approach for the condition is to implement it like this
if (c is Button && c.Text.Equals("Hello")) {
for (int i = 1; i < 3; i++)
{
var buttonName = "button" + i;
Button button = this.Controls.Find(buttonName, true).FirstOrDefault() as Button;
string text = button.Text;
}
try this code.

"Unable to cast object" while looping through programatically created textboxes

I have some Textboxes that are created dynamically --
int i = 1;
while (reader.Read())
{
System.Web.UI.WebControls.TextBox textBox = new System.Web.UI.WebControls.TextBox();
textBox.ID = reader["field_id"].ToString();
textBox.Enabled = false;
HtmlGenericControl div = new HtmlGenericControl("div");
if(i%2 != 0)
div.Attributes.Add("style", "margin-right:120px;padding-bottom:20px;");
if (i % 2 == 0)
div.Attributes.Add("style", "padding-bottom:20px;");
div.Attributes.Add("class", "inline fourcol");
div.InnerHtml = "<label>" + reader["field"] + "</label>";
div.Controls.Add(textBox);
panelId.Controls.Add(div);
textBox.Text = reader["field_value"].ToString();
++i;
}
That works fine (at least i'm sure -they show up how they should). But when i try to loop through them to enable them, or get their values, i get an "Unable to cast object of type 'System.Web.UI.LiteralControl' to type 'System.Web.UI.WebControls.TextBox'. " error.
This is how i've been trying to do it --
public void EditPanel(System.Web.UI.WebControls.Panel panel)
{
foreach (System.Web.UI.WebControls.TextBox t in panel.Controls)
{
t.Enabled = true;
}
}
Thanks!
You're looping over panel.Controls, which will loop over every control in the panel. This is not necessarily the same thing as looping over everything you've added. If there was something else inside the panel that existed when you started, you will end up getting that too.
What you probably wanted was this:
foreach (var t in panel.Controls.OfType<System.Web.UI.WebControls.TextBox>())
{
t.Enabled = true;
}
You are putting each textbox inside a "div" control which is HtmlGenericControl, then inside the panel control. So first you must search for the HtmlGenericControl inside panelId.Controls
A sample code that might help you:
public void EditPanel(System.Web.UI.WebControls.Panel panel)
{
foreach (Control c in panelId.Controls)
{
if (c is HtmlGenericControl)
{
foreach (var textbox in c.Controls.OfType<TextBox>()) //ofType returns IEnumerable<TextBox>
textbox.Enabled = true;
}
}
}
There is a control inside your Panel, that is not a TextBox and could not be cast to it. You should place a breakpoint before the loop and check the panel.Control collection contents in debug mode.
You can avoid the issue if you don't specify a type in the foreach loop and do the safe cast yourself.
foreach (var t in panel.Controls)
{
var textbox = t as System.Web.UI.WebControls.TextBox;
if(textbox != null)
{
textbox.Enabled = true;
}
}
You should check if control is TextBox
public void EditPanel(System.Web.UI.WebControls.Panel panel)
{
foreach (var t in panel.Controls)
{
if (t is System.Web.UI.WebControls.TextBox)
((System.Web.UI.WebControls.TextBox)t).Enabled = true;
}
}
The Controls collection will contain a collection of all the controls in the panel - not just TextBoxes. You can iterate through all of the controls and use the as operator to perform a type cast. If the type cast succeeds then you may enable the textbox.
public void EditPanel(System.Web.UI.WebControls.Panel panel)
{
foreach (var control t in panel.Controls)
{
System.Web.UI.WebControls.TextBox textBox = control as System.Web.UI.WebControls.TextBox;
if (textBox != null)
{
control.Enabled = true;
}
}
}
you add the textbox to the div element and the div element to the panel. therefore you need to select the controls in the panel and then find the textbox.
foreach (var t in panel.Controls.Cast<Control>().SelectMany(c => c.Controls))
{
if (t is TextBox == false) continue;
((TextBox)t).Enabled = true;
}

Object reference not set to an instance of an object exception when assigning a list to a listbox

I wrote the following method to load a list box with values that have not been loaded already but I am getting an Object reference not set to an instance of an object exception when assigning the following. Any information would be helpful. Thanks.
lbxCabinetName.Items.Add(cabinetsCurrentNotUsed[i].ToString());
// Defined outside a method
List<string> cabinetsCurrentNotUsed;
// Set value in the constructor
cabinetsCurrentNotUsed = new List<string>();
Here is the whole procedure.
private void selectCabinetToAdd()
{
// Loop through all server and form cabinet types to see if there are matches
for (int x = 0; x < opticalFile.serverCabinetNames.Count; x++)
{
bool cabinetExists = false;
for (int i = 0; i < opticalFile.CabinetValues.Count; i++)
{
if (opticalFile.serverCabinetNames[x].ToString() == opticalFile.CabinetValues[i].ToString())
{
cabinetExists = true;
}
}
// Add cabinets not used to cabinetsCurrentNotUsed List
if (!cabinetExists)
{
cabinetsCurrentNotUsed.Add(opticalFile.serverCabinetNames[x].ToString());
}
}
// Send cabinetsCurrentNotUsed List to list box
for (int i = 0; i < cabinetsCurrentNotUsed.Count; i++)
{
lbxCabinetName.Items.Add(cabinetsCurrentNotUsed[i].ToString());
}
}
You are trying to add a null to the listbox.
Insted of
for (int i = 0; i < cabinetsCurrentNotUsed.Count; i++)
{
lbxCabinetName.Items.Add(cabinetsCurrentNotUsed[i].ToString());
}
use
foreach (string s in cabinetsCurrentNotUsed)
{
if(s != null)
lbxCabinetName.Items.Add(s);
}
NOTE
This part is not relavant to the question. But in your inner for loop after setting cabinetExists = true; you can break out of the inner loop (if atleast one condition is met you can make sure the cabinetExists is true. you don't have to check for the rest of the items in the inner loop)
EDIT
private void selectCabinetToAdd()
{
foreach (string sc in serverCabinetNames)
{
bool cabinetExists = false;
foreach (string cv in CabinetValues)
{
if (sc == cv)
{
cabinetExists = true;
break;
}
}
if (!cabinetExists)
{
cabinetsCurrentNotUsed.Add(sc);
}
}
foreach (string ccnu in cabinetsCurrentNotUsed)
{
if (ccnu != null)
lbxCabinetName.Items.Add(ccnu);
}
}
Also if your listBox can be null, make sure you check that first before populating the listbox.
if(lbxCabinetName != null)
{
selectCabinetToAdd();
}
EDIT 2
Dynamically adding control
ListBox lbxCabinetName = new ListBox();
lbxCabinetName.Location = new System.Drawing.Point(10, 55);
lbxCabinetName.Size = new System.Drawing.Size(130, 95);
this.Controls.Add(lbxCabinetName);
Strings are nullable so at some point you must be doing something similar to:
cabinetsCurrentNotUsed.Add(null);
Either that or as dbaseman said it is possible lbxCabinetName is null but I'm betting that isn't the case.
As an aside, it's not really a problem but if you're using a generic list of strings the ToString() call isn't necessary. You can just do this:
lbxCabinetName.Items.Add(cabinetsCurrentNotUsed[i]);

how to get value of more than one text box in a loop

I have some text boxes in my page. I want to get all text box values in an array and insert in to table of database.
Is there any option to work by loop
public IEnumerable<string> AllTextsFromTextboxes()
{
foreach (var control in Page.Controls.OfType<TextBox>())
{
yield return control.Text;
}
}
you can try something on these lines, if all the textbox are on the page directly
foreach(Control c in Page.Controls)
{
if (c is TextBox)
{
//get the text
}
}
This will not work for child controls for that you will have to recursively iterate
yes, you can put your controls in panel and then iterate and get value. e.g.
foreach (Control ctrl in Panel1.Controls)
{
if (ctrl.GetType().Name == "TextBox")
{
if (((TextBox)ctrl).Text != string.Empty)
{
// do stuff here
}
}
}
private void FindSelecedControl(Control control)
{
if (control is TextBox)
{
TextBox txt = (TextBox)control;
txt.Enabled = false;
}
else
{
for (int i = 0; i < control.Controls.Count; i++)
{
FindSelecedControl(control.Controls[i]);
}
}
}
foreach (Control control1 in this.Form.Controls)
{
FindSelecedControl(control1);
}

ASP.net -- Identifying a specific control in code behind

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.

Categories