I have 10 text boxes namely TB1, TB2, TB3, TB4 and so on.. to TB10
I want to store them into a single string value named toBeStored.
Now I m doing the manual way
String toBeStored=null;
tobeStored=TB1.text.toString();
tobeStored+=TB2.text.toString();
and so on..
I want to make a for loop and add them
something like this..
for(int i=1;i<11;i++)
{
toBeStored+=TB+i+.text.ToString()+" ";
}
I know that is wrong.. anything to make it right?
No. Because you defined the text boxes as variables there simply is no enumerator defined.
You could define your own enumerator. In the simpliest case that is as simple as
TextBox boxes [] = new TextBox [] { TB1, TB2, TB3....}
foreach (TextBox box in boxes) {
}
While I think the premise may be flawed, you could do this by
for (int i = 1; i <= 10 ; i++) {
TextBox textbox = (TextBox)Page.FindControls( "TB" + i.ToString);
toBeStored += textbox.Text;
}
Put the controls into an array and then iterate the array.
First of all, you didn't tell us whether you're using winforms, webforms, or what. That would be good.
Second, you probably don't need to use .ToString() on the Text property, which I would assume is already a string.
Finally, if you insist on being lazy, then put the text boxes into an array, and loop over the array:
private TextBox[] _textBoxes = new TextBox[10];
// In init code:
TextBox[0] = TB1;
TextBox[1] = TB2;
// ...
StringBuilder toBeStored = new StringBuilder();
for (int i=0; i<10; i++)
{
toBeStored.Append(TextBox[i].Text);
}
// Now process toBeStored.ToString();
You can use reflection in general if you want to get a field by name.
Type type = GetType();
for (int i = 1; i <= 10; i++)
{
var name = "TB" + i;
var field = type.GetField(name, BindingFlags.Instance | BindingFlags.NonPublic); //or appropriate flags
TextBox tb = (TextBox)field.GetValue(this);
//...
}
If was to do such a thing I would create a helper method to accumulate the text into a string.
public string AccumulateNames(params string[] names)
{
return names.Aggregate(string.Empty, (current, name) => current + name);
}
which would be called similar to this
var toBeStored = AccumulateNames(TB1.Text, TB2.Text, ..., TBn.Text);
Related
So I am so fresh into the world of programming, starting new, I decided to start messing around in C# to create simple apps from ideas that come to mind, with this little app, I'm trying to have multiple TextBoxes named d1,d2,d3,d4,etc... the user inserts numbers into the textboxes then clicks button1, which begins the process in the code below creating a new list which contains all of the values of the textboxes and then the list is converted to an array and the array is then converted into an int array, etc....
BUT, when starting the application and I add values to the textboxes and then click button1, it shows 2 error like shows in the //gray code line below
Please help.
private void button1_Click(object sender, EventArgs e)
{
List<string> dodo = new List<string>();
dodo.Add(d1.Text); dodo.Add(d2.Text); dodo.Add(d3.Text); dodo.Add(d4.Text); dodo.Add(d5.Text);
dodo.Add(d6.Text); dodo.Add(d7.Text); dodo.Add(d8.Text); dodo.Add(d9.Text); dodo.Add(d10.Text);
dodo.Add(d11.Text); dodo.Add(d12.Text); dodo.Add(d13.Text); dodo.Add(d14.Text); dodo.Add(d15.Text);
dodo.Add(d16.Text); dodo.Add(d17.Text); dodo.Add(d18.Text); dodo.Add(d19.Text); dodo.Add(d20.Text);
foreach(string numb in dodo)
{
if (numb == "")
numb = "0"; //numb word has a red underline
}
string[] terms = dodo.ToArray();
int[] valv = {};
int x = 0;
for(int i=0;i<=19;i++)
{
valv[i] = int.Parse(terms[i]); //the ; in the end has a red underline and shows "FormatException was unhandled" error
i++;
x = x + valv[i];
}
string myString;
myString = x.ToString();
Result1.Text = myString;
}
you can't change the iteration variable which is numb in your case. Please change in the List container instead
List<string> dodo = new List<string>();
dodo.Add(d1.Text); dodo.Add(d2.Text); dodo.Add(d3.Text); dodo.Add(d4.Text); dodo.Add(d5.Text);
dodo.Add(d6.Text); dodo.Add(d7.Text); dodo.Add(d8.Text); dodo.Add(d9.Text); dodo.Add(d10.Text);
dodo.Add(d11.Text); dodo.Add(d12.Text); dodo.Add(d13.Text); dodo.Add(d14.Text); dodo.Add(d15.Text);
dodo.Add(d16.Text); dodo.Add(d17.Text); dodo.Add(d18.Text); dodo.Add(d19.Text); dodo.Add(d20.Text);
int k = 0;
foreach (string numb in dodo)
{
if (numb == "")
{
//numb = "0"; //numb word has a red underline
dodo[k] = "0";
}
k++;
}
Now your code on parsing into integer won't give any runtime error.
The first line "tells" you that you are not able to assign a new value to the variable which is used as a foreach iteration variable.
The second line, "tells" you that you have string value which is not able to be parsed correctly (e.g. user put string which is not a number). To avoid this you can use Int32.TryParse method instead, which will safely try to parse the given string.
The best and easiest way to achieve what you need is using LINQ methods, here is the example based on few things/assumptions:
Since you are converting empty strings into zeros, you could simply skip those entries from counting
To avoid FormatException, you should use TryParse method instead. Since TryParse method will safely parse the given string, you don't even have to filter empty strings at all (they will be skipped). However, I deliberately left filtering part, to get you a better overview of a solution.
You can use list initializer to make list initialization more readable
Solution:
List<string> dodo = new List<string>()
{
d1.Text, d2.Text //...others
};
int sum = dodo
.Where(item => !String.IsNullOrEmpty(item))
.Sum(item =>
{
if (Int32.TryParse(item, out int parsedItem))
{
return parsedItem;
}
return 0;
});
You can get more familiar with LINQ and used methods on following link
I am writing a C#/ASP.Net web application and I have a large number of text boxes that need to be set to variable values in the code behind. Currently I am doing the following:
AspTextBox0.Text = codeBehindVariable[0];
AspTextBox1.Text = codeBehindVariable[1];
AspTextBox2.Text = codeBehindVariable[2];
AspTextBox3.Text = codeBehindVariable[3];
…
Is there an easy way to do this in a simple “for” loop??
This is a very simplified example, the real program has a switch case and some other testing that needs to be performed at the time the variable is assigned. Therefore, a “for” loop would drastically simplify the writing and maintainability of the code. Back in the good-old-days of VB6 and control arrays this was a piece of cake.
The good old days of VB6 are long gone and better don't come back.
Create a control array or better a List<TextBox> yourself:
var textBoxes = new List<TextBox> {
AspTextBox0,
AspTextBox1,
// ...
};
Then Zip it with the codeBehindVariable:
textBoxes.Zip(codeBehindVariable,
(textBox, variable) => textBox.Text = variable);
Or, if you prefer a for loop:
for ( int i = 0; i < codeBehindVariable.Length; i++ )
{
textBoxes[i].Text = codeBehindVariable[i];
}
Keep in mind that in the for loop you will have to make sure that both textBoxes and codeBehindVariable have the same number of items (or make the loop run only over the shortest list's amount of entries). The Zip function will take care of this by itself.
Assuming you are in a class that implements System.Web.UI.Page you can try to look up the control to find the one you want like so:
for (int i = 0; i <= codeBehindVariable.Length; i++)
{
var textBox = FindControl("AspTextBox" + i, false);
if(textBox != null)
{
textBox.Text = codeBehindVariable[i];
}
}
you can do something like this...
int i = 0;
foreach (Control ctrl in this.Controls)
{
if (ctrl is TextBox)
{
TextBox tempTextBox = (TextBox)ctrl;
tempTextBox.Text = codeBehindVariable[i];
i++;
}
}
I have a number of variables named test1....test10 they are all declared as a string.
what I want to do is access them from inside a loop using the loop counter something like this:
string test1;
//...
string test10;
for (int i = 1; i < 10; i++)
{
test + i.ToString() = "some text";
}
any idea how I could do this?
this is a WPF .net 4 windows App.
Simple answer: don't have 10 variables, have one variable which is a collection:
List<string> test = new List<string>();
for (int i = 1; i < 10; i++)
{
test.Add("some text");
}
Having lots of variables which logically form a collection is a design smell.
(If you really have to do this, you could use reflection. But please don't.)
You simply can't, use a List or a String-Array for this purpose.
List
List<String> myStrings = new List<String>();
for (Int32 i = 0; i < 10; i++)
{
myStrings.Add("some text");
}
String-Array
String[] myStrings = new String[10];
for (Int32 i = 0; i < myStrings.length; i++)
{
myStrings[i] = "some text";
}
Try adding them to an array of string[] or simply create a List<string> list = new List<string>();.
With the list, you can iterate easily.
This is not really possible, unless you use the dynamic keyword, and then you will get a property instead of a true variable. Take a look at ExpandoObject, it will allow you to add properties based on a string variable.
In your case, as other have said, you really should use a List<string>
For something as simple as 10 items, an array is the best way to go. Fast and easy.
For example in Windows Form, you have textboxes textbox0 to textbox29 and you need to assign them all to an array. What I currently can think of is to do this:
array[0] = textbox0;
array[1] = textbox1;
...
array[29] = textbox29;
Is it possible for me to do something like this:
for(int i=0; i<30; i++)
{
array[i] = textbox + i;
//and some magic is done such tt this is a variable, eg. textbox1
}
this.Controls.OfType<TextBox>().ToArray()
should work. It selects the controls which are TextBox and then converts them to an array.
From the top of my head:
int i = 0;
foreach (Control c in FormX.Controls)
{
int i2;
if (c.Name.StartsWith("textbox") && int.TryParse(c.Name.Substring(7),out i2))
{
array[i] = c;
i++;
}
}
array = array.OrderBy(a => Convert.ToInt32(a.Name.Substring(7))).ToArray();
Well, you could use reflection... but personally I'd try to avoid creating all those separate variables to start with. For example, if you really need designer support, you could avoid creating separate variables but create the array by finding the controls by name.
Alternatively, if you can just autogenerate the controls programmatically in a loop, I'd do that.
I am modifying #rdkleine code
Control[] array = new Control[100];
foreach (Control c in FormX.Controls)
{
int index;
if (c.Name.StartsWith("textbox") && int.TryParse(c.Name.Substring(7),out index))
{
array[index] = c;
}
}
I think this should place the controls in the correct index in the array.
The following is an extract from my code:
public class AllIntegerIDs
{
public AllIntegerIDs()
{
m_MessageID = 0;
m_MessageType = 0;
m_ClassID = 0;
m_CategoryID = 0;
m_MessageText = null;
}
~AllIntegerIDs()
{
}
public void SetIntegerValues (int messageID, int messagetype,
int classID, int categoryID)
{
this.m_MessageID = messageID;
this.m_MessageType = messagetype;
this.m_ClassID = classID;
this.m_CategoryID = categoryID;
}
public string m_MessageText;
public int m_MessageID;
public int m_MessageType;
public int m_ClassID;
public int m_CategoryID;
}
I am trying to use the following in my main() function code:
List<AllIntegerIDs> integerList = new List<AllIntegerIDs>();
/* some code here that is ised for following assignments*/
{
integerList.Add(new AllIntegerIDs());
index++;
integerList[index].m_MessageID = (int)IntegerIDsSubstring[IntOffset];
integerList[index].m_MessageType = (int)IntegerIDsSubstring[IntOffset + 1];
integerList[index].m_ClassID = (int)IntegerIDsSubstring[IntOffset + 2];
integerList[index].m_CategoryID = (int)IntegerIDsSubstring[IntOffset + 3];
integerList[index].m_MessageText = MessageTextSubstring;
}
Problem is here: I am trying to print all elements in my List using a for loop:
for (int cnt3 = 0 ; cnt3 <= integerList.FindLastIndex ; cnt3++) //<----PROBLEM HERE
{
Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\n", integerList[cnt3].m_MessageID,integerList[cnt3].m_MessageType,integerList[cnt3].m_ClassID,integerList[cnt3].m_CategoryID, integerList[cnt3].m_MessageText);
}
I want to find the last element so that I equate cnt3 in my for loop and print out all entries in the List. Each element in the list is an object of the class AllIntegerIDs as mentioned above in the code sample. How do I find the last valid entry in the List?
Should I use something like integerList.Find(integerList[].m_MessageText == null;?
If I use that it will need an index that will range from 0 to whatever maximum. Means I will have to use another for loop which I do not intend to use. Is there a shorter/better way?
To get the last item of a collection use LastOrDefault() and Last() extension methods
var lastItem = integerList.LastOrDefault();
OR
var lastItem = integerList.Last();
Remeber to add using System.Linq;, or this method won't be available.
If you just want to access the last item in the list you can do
if (integerList.Count > 0)
{
// pre C#8.0 : var item = integerList[integerList.Count - 1];
// C#8.0 :
var item = integerList[^1];
}
to get the total number of items in the list you can use the Count property
var itemCount = integerList.Count;
In C# 8.0 you can get the last item with ^ operator full explanation
List<char> list = ...;
var value = list[^1];
// Gets translated to
var value = list[list.Count - 1];
Lets get at the root of the question, how to address the last element of a List safely...
Assuming
List<string> myList = new List<string>();
Then
//NOT safe on an empty list!
string myString = myList[myList.Count -1];
//equivalent to the above line when Count is 0, bad index
string otherString = myList[-1];
"count-1" is a bad habit unless you first guarantee the list is not empty.
There is not a convenient way around checking for the empty list except to do it.
The shortest way I can think of is
string myString = (myList.Count != 0) ? myList [ myList.Count-1 ] : "";
you could go all out and make a delegate that always returns true, and pass it to FindLast, which will return the last value (or default constructed valye if the list is empty). This function starts at the end of the list so will be Big O(1) or constant time, despite the method normally being O(n).
//somewhere in your codebase, a strange delegate is defined
private static bool alwaysTrue(string in)
{
return true;
}
//Wherever you are working with the list
string myString = myList.FindLast(alwaysTrue);
The FindLast method is ugly if you count the delegate part, but it only needs to be declared one place. If the list is empty, it will return a default constructed value of the list type "" for string. Taking the alwaysTrue delegate a step further, making it a template instead of string type, would be more useful.
int lastInt = integerList[integerList.Count-1];
Though this was posted 11 years ago, I'm sure the right number of answers is one more than there are!
You can also doing something like;
if (integerList.Count > 0)
var item = integerList[^1];
See the tutorial post on the MS C# docs here from a few months back.
I would personally still stick with LastOrDefault() / Last() but thought I'd share this.
EDIT;
Just realised another answer has mentioned this with another doc link.
Change
for (int cnt3 = 0 ; cnt3 <= integerList.FindLastIndex ; cnt3++)
to
for (int cnt3 = 0 ; cnt3 < integerList.Count; cnt3++)
Use the Count property. The last index will be Count - 1.
for (int cnt3 = 0 ; cnt3 < integerList.Count; cnt3++)
Why not just use the Count property on the List?
for(int cnt3 = 0; cnt3 < integerList.Count; cnt3++)
Independent of your original question, you will get better performance if you capture references to local variables rather than index into your list multiple times:
AllIntegerIDs ids = new AllIntegerIDs();
ids.m_MessageID = (int)IntegerIDsSubstring[IntOffset];
ids.m_MessageType = (int)IntegerIDsSubstring[IntOffset + 1];
ids.m_ClassID = (int)IntegerIDsSubstring[IntOffset + 2];
ids.m_CategoryID = (int)IntegerIDsSubstring[IntOffset + 3];
ids.m_MessageText = MessageTextSubstring;
integerList.Add(ids);
And in your for loop:
for (int cnt3 = 0 ; cnt3 < integerList.Count ; cnt3++) //<----PROBLEM HERE
{
AllIntegerIDs ids = integerList[cnt3];
Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\n",
ids.m_MessageID,ids.m_MessageType,ids.m_ClassID,ids.m_CategoryID, ids.m_MessageText);
}
I would have to agree a foreach would be a lot easier something like
foreach(AllIntegerIDs allIntegerIDs in integerList)
{
Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\n", allIntegerIDs.m_MessageID,
allIntegerIDs.m_MessageType,
allIntegerIDs.m_ClassID,
allIntegerIDs.m_CategoryID,
allIntegerIDs.m_MessageText);
}
Also I would suggest you add properties to access your information instead of public fields, depending on your .net version you can add it like public int MessageType {get; set;} and get rid of the m_ from your public fields, properties etc as it shouldnt be there.