how to define an array of textboxes in c#? - c#

Hi when I create textboxes on Windows Application Form I cannot name it as box[0], box[1] and so on. The purpose why I want to do like this is because I want to use them in a loop.

Actually I found TextBox[] array = { firstTextBox, secondTextBox }; works too!

How about making a list of them after you create them? In your form initialization function, you can do something like:
List<TextBox> myTextboxList = new List<TextBox>();
myTextBoxList.Add(TextBox1);
myTextBoxList.Add(TextBox2);
mytextBoxList.Add(TextBox3);
Now you can itterate through with your "myTextboxList" with something like below:
Foreach (TextBox singleItem in myTextboxList) {
// Do something to your textboxes here, for example:
singleItem.Text = "Type in Entry Here";
}

You can create textboxes on runtime and just put them in an array...
If you want to do it in design time, you will have to do some control filtering logic on the whole this.Controls array in order to access only the wanted textboxes. Consider if (currControl is TextBox) if all textboxes in the form are ones you want in the array.
Another option for design time, is putting all wanted textboxes in a panel which will be their parent, and then iterating over the panel's children (controls) and cast them to TextBox.
A runtime solution would be something like:
var arr = new TextBox[10];
for (var i = 0; i < 10; i++)
{
var tbox = new TextBox();
// tbox.Text = i.ToString();
// Other properties sets for tbox
this.Controls.Add(tbox);
arr[i] = tbox;
}

I wouldn't use an array for this, personally. I would use some form of generic collection, like List.
List<TextBox> textBoxList = new List<TextBox>();
//Example insert method
public void InsertTextBox(TextBox tb)
{
textBoxList.Add(tb);
}
//Example contains method
public bool CheckIfTextBoxExists(TextBox tb)
{
if (textBoxList.Contains(tb))
return true;
else
return false;
}
You don't necessarily have to use the Contains method, you could also use Any(), or maybe even find another way- all depends on what you're doing. I just think using a generic collection gives you more flexibility than a simple array in this case.

for C# just use this to create an array of text boxes
public Text [] "YourName" = new Text ["how long you want the array"];
then add the text boxes to the array individually.

TextBox Array using C#
// Declaring array of TextBox
private System.Windows.Forms.TextBox[] txtArray;
private void AddControls(int cNumber)
{
// assign number of controls
txtArray = new System.Windows.Forms.TextBox[cNumber + 1];
for (int i = 0; i < cNumber + 1; i++)
{
// Initialize one variable
txtArray[i] = new System.Windows.Forms.TextBox();
}
}

TextBox[] t = new TextBox[10];
for(int i=0;i<required;i++)
{
t[i]=new TextBox();
this.Controls.Add(t[]);
}

Related

How to access a group of Text Boxes based on the Index Id in their Name

I have 16 text boxes in my Form whose names are suffixed sequentially from 1 to 16 respectively.
i.e. The 16 test boxes are names TextBox1, 'TextBox2, .... all the way until the 16th one, which is namedTextBox16`.
I would like to read the contents of these 16 text boxes in a loop and modify the ith TextBox's contents or properties based on a certain condition.
How do I do this?
If you use WinForms, easiest way is to store text boxes references in array, in constructor of window:
TextBox[] data = new TextBox[16]{textBox1,textBox2, [...],textBox16};
then you can use for loop to access them.
You can try something like this:
Dictionary<string, string> yourValues = new Dictionary<string, string>();
foreach (Control x in this.Controls)
{
if (x is TextBox)
{
yourValues.Add(((TextBox)x).Name, ((TextBox)x).Text);
}
}
NOTE: On your future question please provide more information and make your question more clear.
i would try to find and modify using Linq:
using System.Linq;
//...
int x = 5; //number of textbox to search
var textbox = this.Controls.OfType<TextBox>().Single(tb => tb.Name.EndsWith(x.ToString()));
textbox.Text = "abc";
In case you have to loop thru all the texboxes in form, you can do something like this:
List<TextBox> textboxes = this.Controls.OfType<TextBox>().ToList();
foreach (TextBox box in textboxes)
{
box.Text = "something";
}
Easiest way according to what you specified is to use Linq.
Let's assume you have 3 TextBoxes :
// 1st -> which is named meTextBox1
// 2nd -> which is named meTextBox2
// 3rd -> which is named meTextBox3
As you can see from above every line differs only by the number ( index .. call it whatever you want ).
Now you can make your base "query" which would look like :
const string TB_NAME = "meTextBox{0}";
And as you can presume right now this will be used inside of string.Format method. Now to retrieve desired TextBox all you have to do is to make Linq statement :
string boxName = string.Format(TB_NAME, 7); // retrieve 7th text box
TextBox tBox = Controls.OfType<TextBox>().FirstOrDefault(tb => tb.Name == boxName);
This example does not consider nested Controls but you can make do this recursively which will retrieve nested Controls:
TextBox ByIndex(int idx, Control parent)
{
TextBox result = null;
string searchFor = string.Format(TB_NAME, idx);
foreach(Control ctrl in parent.Controls)
{
if(!(ctrl is TextBox) && ctrl.HasChildren)
{
result = ByIndex(idx, ctrl);
if( result != null)
break;
}
else if(ctrl is TextBox)
{
if(ctrl.Name = searchFor)
{
result = ctrl as TextBox;
break;
}
}
}
return result;
}
To use above method you can just call it like such :
public class MeForm : Form
{
//.. your code here ..
void meImaginaryMethodToRetrieveTextBox()
{
int meRandomIndex = 7;
TextBox tb = ByIndex(meRandomIndex, this);
// rest of the code...
}
}

modifying a group of WinForm controls using a loop?

I have a group of textbox controls that i would like to populate with an array of doubles.The controls names are numerically incremented like so
Tol1.Text = lineTolFront[0].ToString();
Tol2.Text = lineTolFront[1].ToString();
Tol3.Text = lineTolFront[2].ToString();
Tol4.Text = lineTolFront[3].ToString();
Tol5.Text = lineTolFront[4].ToString();
Tol6.Text = lineTolFront[5].ToString();
//and so on
is there a simpler way to do this using a loop without having to manually input the values?
First, get all those TextBoxes using LINQ (note: this is useful particularly when you have many controls you do not want manually put in a collection).
var tboxes = this.Controls.Cast<Control>()
.OfType<TextBox>()
.Where(l => l.Name.Contains("Tol"));
and then loop through them and set the content.
int i = 0;
foreach(var tb in tboxes)
tb.Text = lineTolFront[i++].ToString();
You could add the TextBoxes to a collection first. It's a little less copy/paste work at least.
var textBoxes = new List<TextBox> { Tol1, Tol2, Tol3, Tol4, Tol5, Tol6 };
for (var i = 0; i < lineTolFront.Count; i++)
textBoxes[i].Text = lineTolFront[i].ToString();
Regarding M Patel's comment, make sure you add the TextBoxes to the collection in the same order you want to assign the doubles from the lineTolFront array.
You could add your controls to an array and loop through it:
var controls = new[] { Tol1, Tol2, Tol3, Tol4, Tol5, }; //etc
for(int i = 0; i < controls.Length; i++)
{
controls[i].Text = lineTolFront[i].ToString();
}

How can I use some controls on the form such an array of them

I have about 20 checkboxes on the form. How can I name them to use them later in a for loop for example? A thing such an array checkBox[i].
Regards
I am assuming that the controls are being created as part of InitializeComponent(), i.e. it's done by designer code.
The straightforward approach would be to do this after InitializeComponent is called:
var checkboxes = new[]
{
checkBox1, // these are the names you have given
checkBox2, // to the checkboxes in the designer
checkBox3,
};
A better way would be to use LINQ to put all checkboxes in an array:
var checkboxes = this.Controls.OfType<CheckBox>().ToArray();
However, this will not work recursively and you may have to filter some checkboxes out of the collection if you don't want all of them to be in the array.
Info here: http://msdn.microsoft.com/en-us/library/aa289500(v=vs.71).aspx
Check out container controls, they automatically create collections of the controls you place within them in design view.
CheckBox[] MyCheckBoxes = new CheckBox[20];
for (int i = 0; i < 20; i++)
{
MyCheckBoxes[i] = new CheckBox();
MyCheckBoxes[i].Checked = true;
//etc
}

Dynamic Variable Name Use in C# for WinForms

Not sure what is the best way to word this, but I am wondering if a dynamic variable name access can be done in C# (3.5).
Here is the code I am currently looking to "smarten up" or make more elegant with a loop.
private void frmFilter_Load(object sender, EventArgs e)
{
chkCategory1.Text = categories[0];
chkCategory2.Text = categories[1];
chkCategory3.Text = categories[2];
chkCategory4.Text = categories[3];
chkCategory5.Text = categories[4];
chkCategory6.Text = categories[5];
chkCategory7.Text = categories[6];
chkCategory8.Text = categories[7];
chkCategory9.Text = categories[8];
chkCategory10.Text = categories[9];
chkCategory11.Text = categories[10];
chkCategory12.Text = categories[11];
}
Is there a way to do something like ("chkCategory" + i.ToString()).Text?
Yes, you can use
Control c = this.Controls.Find("chkCategory" + i.ToString(), true).Single();
(c as textBox).Text = ...;
Add some errorchecking and wrap it in a nice (extension) method.
Edit: It returns Control[] so either a [0] or a .Single() are needed at the end. Added.
for(...)
{
CheckBox c = this.Controls["chkCategory" + i.ToString()] as CheckBox ;
c.Text = categories[i];
}
You can do that with reflection. But don't.
It's more proper to instantiate a list of contols, add them programmatically to your form, and index that.
Sometimes it can help to put your controls into an array or collection as such:
Checkbox[] chkCataegories = new Checkbox[] { chkCategory1, chkCategory2 ... };
for(int i = 0; i < chkCategories.Length; i++)
chkCategories[i].Text = categories[i];
As another approach, you can dynamically create your checkboxes at runtime instead of design time:
for(int i = 0; i < categories.Length; i++)
{
Checkbox chkCategory = new chkCategory { Text = categories[i] };
someContainer.Controls.Add(chkCategory);
}
At least with dynamically created controls, you don't need to modify your GUI or your form code whenever you add new categories.
You don't need dynamic for that. Put chkCategory1 - 12 in an array, and loop through it with a for loop. I would suggest you keep it around in a field and initialize it at form construction time, because chkCategory seems to be related. But if you want a simple example of how to do it in that simple method, then it would be something like this:
private void frmFilter_Load(object sender, EventArgs e)
{
var chkCategories = new [] { chkCategory1, chkCategory2, chkCategory3, .......... };
for(int i = 0 ; i < chkCategories.Length ; i++ )
chkCategoies[i].Text = categories[i];
}
You know more about the application, so you could perhaps avoid writing out all the control names - for instance, if they are placed on a common parent control, then you could find them by going through it's children.
No, but you could do something like this (untested, beware of syntax errors):
private readonly CheckBox[] allMyCheckboxes = new CheckBox[] { chkCategory1, chkCategory2, ... }
Then you just need to do
for (i = 0; i < 12; i++) allMyCheckboxes[i].Text = categories[i];
The "this.Controls["chkCategory" + i.ToString()]" and "this.Controls.Find("chkCategory" + i.ToString(), true)" both do not work... the former informs you that the contents of the [] are not an int and the latter that ControlCollection does not contain a definition for Find.
Use "Control myControl1 = FindControl("TextBox2");" instead.
I needed this form as I was looping through another array, extracting values and using them to populate form fields. Much easier to look for label1, label2, label3, etc.

How can I programmatically construct the object reference?

Lets just say that I have three textboxes: TextBox1, TextBox2, TextBox3. Normally if I wanted to change the text for example I would put TextBox1.Text = "Whatever" and so on. For what I'm doing right now I would like to something like (TextBox & "i").Text. That obviously isn't the syntax I need to use I'm just using it as an example for what I need to do. So how can I do something like this? The main reason I'm doing this is to reduce code with a loop.
Please keep in mind that I'm not actually changing the text of the textboxes I'm simply using that as an example to get the point across.
Use an array to access the TextBox objects by index:
TextBox[] textBoxes = new TextBox[3];
textBoxes[0] = textBox1;
textBoxes[1] = textBox2;
textBoxes[2] = textBox3;
for (int i = 0; i < 3; i++)
{
textBoxes[i].Text = "Whatever";
}
this.Controls.OfType<TextBox>().First(r => r.ID == "textbox1").Text = "whatever";
if you know of course, that textbox with id 'textbox1' exists
or
foreach (var tb in this.Controls.OfType<TextBox>()) {
tb.Text ="whatever";
}
When you create your TextBox dynamically you can use an array of TextBoxes which is much easier.
However it is possible to use reflection, too:
var textBoxes = GetType().GetFields( BindingFlags.NonPublic | BindingFlags.Instance )
foreach( var fieldInfo in textBoxes )
{
if( fieldInfo.FieldType == typeof( TextBox ) )
{
var textBox = ( TextBox )fieldInfo.GetValue( this );
textBox.Text = "";
}
}
I would recommend not doing this in general. Often, it's best to put your object references into a collection, and then work on the collection - or to use some other approach along those lines.
However, it is possible to do this (though it's slow) via Reflection:
var fields = this.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic).Where(f => f.Name.StartsWith("TextBox"));
foreach(var field in fields)
{
TextBox box = field.GetValue(this) as TextBox;
if (box != null)
box.Text = "Whatever";
}
As the goal is to reduce code size, no, you can't do that. Near to what you are trying to achieve would be:
to save the controls in a List or Array
loop the List or Array
List<TextBox> myTxts = new List<TextBox> {textBox1, textBox2, textBox3};
foreach(TextBox txt in myTxts) {
txt.Text = "";
}
Another approach would be to poll the Controls Collection of the Form
foreach(Control ctl in this.Controls) {
var txt = ctl as TextBox;
if (txt != null) {
txt.Text = "";
}
}

Categories