I have 50 text boxes starting from TextBox1 till TextBox50. I want to retrieve values from all these 50 text boxes. I tried looping but it failed. I want some code like TextBox(i).Text where i varies from 1 to 50.
The loop should produce the following result.
Response.Write(TextBox1.Text);
Response.Write(TextBox2.Text);
son on till
Response.Write(TextBox50.Text);
How can I achieve this?
You can use FindControl which takes a string as parameter, pass it "TextBox" + i like:
TextBox tb = this.FindControl("TextBox" + i) as TextBox;
if (tb != null)
{
Response.Write(tb.Text);
}
You can loop thought them simply as following :
string value=""; // store each textbox value in this variable
foreach (Control x in this.Controls) // loop through the controls in the form
{
if (x is TextBox) // if the program found a textbox in the form
{
value = (x as TextBox).Text; // set the value of the textbox number x to the string value
listBox1.Items.Add(value); // here is a listbox to show the resule
}
}
Related
I've been trying to add a few candles to an array so I can use that array for the rest of my code, using the candles' properties more easily. However it doesn't seem as my code is correct and I would love someone to help me with this. (Color != DarkGoldenrod differentiates the candles from the other labels in my project, all of which have the same color)
private Label[] CandlesToMatrix()
{
Label[] candles = new Label[7];
foreach (Control ctrl in this.Controls)
{
if ((ctrl is Label) && (ctrl.BackColor != Color.DarkGoldenrod))
{
for (int i = 0; i < 7; i++)
{
candles[i] = (Label)ctrl;
}
}
}
return candles;
}
The problem you are facing is that you assign each element in the array the control that matches the criteria.
The code runs like: Enumerate all controls and check if it is a label and not some specific color. If he finds one, he will fill up the whole array with a reference to that control. If the array was already filled by the previous match, it will be overwritten.
So you end up with an array filled with either a null or the last matching control.
I think you would like to have the array filled with 'unique' controls. So every time you find a match, you have to increase the index to write it to.
For example:
private Label[] CandlesToMatrix()
{
Label[] candles = new Label[7];
// declare a variable to keep hold of the index
int currentIndex = 0;
foreach (Control ctrl in this.Controls)
{
if ((ctrl is Label label) && (label.BackColor != Color.DarkGoldenrod))
{
// check if the currentIndex is within the array. Never read/write outside the array.
if(currentIndex == candles.Length)
break;
candles[currentIndex] = label;
currentIndex++;
}
}
}
I'll add another example......
C# has so much more to offer. This is a little old c programming style. Fixed size arrays etc. In C# you have also a List which uses the type you use between the < and >. For example. List<Label>.
Here is an example which uses a List.
private Label[] CandlesToMatrix()
{
List<Label> candles = new List<Label>();
// int currentIndex = 0; You don't need to keep track of the index. Just add it.
foreach (Control ctrl in this.Controls)
{
if ((ctrl is Label label) && (label.BackColor != Color.DarkGoldenrod))
{
candles.Add(label);
}
}
return candles.ToArray(); // if you still want the array as result.
}
and... you could also use Linq (which is a next step)
private Label[] CandlesToMatrix()
{
return this.Controls
// check the type.
.OfType<Label>()
// matches it the creteria?
.Where(label => ((ctrl is Label label) && (label.BackColor != Color.DarkGoldenrod))
// fillup an array with the results
.ToArray();
}
I'm making a sudoku in Windows Form Application.
I have 81 textboxes and I have named them all textBox1a, textBox1b... textBox2a, textBox2b...
I want to make it so that if any of the textboxes, in any of the rows, is equal to any other textbox in the same row, then both will get the background color red while the textboxes are equal.
I tried using this code just for test:
private void textBox1a_TextChanged_1(object sender, EventArgs e)
{
while (textBox1a.Text == textBox1b.Text)
{
textBox1a.BackColor = System.Drawing.Color.Red;
textBox1b.BackColor = System.Drawing.Color.Red;
}
It didn't work, and I don't know where I should put all this code, I know I shouldn't have it in the textboxes.
Should I use a code similar to this or is it totally wrong?
You want to iterate over the collection of text boxes just once, comparing it to those that haven't yet been compared against. If you have your textboxes in an array (let's call it textBoxes), and know which one was just changed (e.g. from the textChanged handler), you could do:
void highlightDuplicates(int i) // i is the index of the box that was changed
{
int iVal = textBoxes[i].Text;
for (int j = 0; j < 82; j++)
{
// don't compare to self
if (i == j) return;
if (textBoxes[j].Text == iVal)
{
textBoxes[i].BackgroundColor = System.Drawing.Color.Red;
textBoxes[j].BackgroundColor = System.Drawing.Color.Red;
}
}
}
If you wanted to get fancier, you could put your data in something like: Dictionary<int, TextBox>, where the key is the value and the TextBox is a reference to the text box with that value. Then you can quickly test for duplicate values with Dictionary.Contains() and color the matching text box by getting its value.
I think your current code would result in an infinite loop. The textboxes' values can't change while you are still in the event handler, so that loop would never exit.
If all of your boxes are named according to one convention, you could do something like this. More than one input can use the same handler, so you can just assign this handler to all the boxes.
The following code is not tested and may contain errors
private void textBox_TextChanged(object sender, EventArgs e){
var thisBox = sender as TextBox;
//given name like "textBox1a"
var boxNumber = thisBox.Name.SubString(7,1);
var boxLetter = thisBox.Name.SubString(8,1);
//numbers (horizontal?)
for(int i = 1; i<=9; i++){
if(i.ToString() == boxNumber)
continue; //don't compare to self
var otherBox = Page.FindControl("textBox" + i + boxLetter) as TextBox;
if (otherBox.Text == thisBox.Text)
{
thisBox.BackColor = System.Drawing.Color.Red;
otherBox.BackColor = System.Drawing.Color.Red;
}
}
//letters (vertical?)
for(int i = 1; i<=9; i++){
var j = ConvertNumberToLetter(i); //up to you how to do this
if(j == boxLetter)
continue; //don't compare to self
var otherBox = Page.FindControl("textBox" + boxNumber + j) as TextBox;
if (otherBox.Text == thisBox.Text)
{
thisBox.BackColor = System.Drawing.Color.Red;
otherBox.BackColor = System.Drawing.Color.Red;
}
}
}
I believe you will be more effective if create an Array (or a List) of Integers and compare them in memory, against compare them in UI (User Interface).
For instance, you could:
1) Create an Array of 81 integers.
2) Everytime the user input a new number, you search for it in that Array. If found, set the textbox as RED, otherwise, add the new value to that array.
3) The ENTER event may be allocated fot the entire Textboxes (utilize the Handles keyword with all Textboxes; like handles Text1.enter, Text2.enter, Text3.enter ... and so forth)
Something like:
int[] NumbersByUser = new int[81];
Private Sub Textbox1.Enter(sender as object, e as EventArgs) handles Textbox1.Enter, Textbox2.Enter, Textbox3.enter ...
int UserEntry = Convert.ToInt32(Sender.text);
int ValorSelecionado = Array.Find(NumbersByUser, Z => (Z == UserEntry));
if (ValorSelecionado > 0) {
Sender.forecolor = Red;
}
else
{
NumbersByUser(Index) = UserEntry;
}
You should have a 2 dimensional array of numbers (could be one dimensional, but 2 makes more sense) let's assume its called Values. I suggest that you have each textbox have a incrementing number (starting top left, going right, then next row). Now you can do the following:
All TextBox Changed events can point to the same function. The function then takes the tag to figure out the position in the 2dim array. (X coordinate is TAG % 9 and Y coordinate is TAG / 9)
In the callback you can loop over the textboxes and colorize all boxes as you like. First do the "check row" loop (pseudo code)
var currentTextBox = ((TextBox)sender)
var x = ((int)currentTextBox.Tag) % 9
var y = ((int)currentTextBox.Tag) / 9
// First assign the current value to the backing store
Values[currentTextBox] = int.parse(currentTextBox.Text)
// assuming variable x holding the column and y holding the row of current box
// Array to hold the status of a number (is it already used?)
bool isUsed[9] = {false, false, ...}
for(int col = 0; col <= 9; i++)
{
// do not compare with self
if(col == x) continue;
isUsed[textBox] = true;
}
// now we have the status of all other boxes
if( isUsed[Values[x,y]] ) currentTextBox.Background = Red else currentTextBox.Background = Green
// now repeat the procedure for the column iterating the rows and for the blocks
I would suggest a dynamic approach to this. Consider each board item as a cell (this would be it's own class). The class would contain a numeric value and other properties that could be useful (i.e. a list of possible values).
You would then create 3 collections of the cells, these would be:
A collection of rows of 9 cells (for tracking each row)
A collection of columns of 9 cells (for tracking each column)
A collection of 3x3 cells
These collections would share references - each cell object would appear once in each collection. Each cell could also contain a reference to each of the 3 collections.
Now, when a cell value is changed, you can get references to each of the 3 collections and then apply a standard set of Sudoku logic against any of those collections.
You then have some display logic that can walk the boards of cells and output to the display (your View) your values.
Enjoy - this is a fun project.
I have this code that is suppose to check each label for the word "closed", and after its done checking it will remove all the text that is in the labels and place everything thats NOT labeled "closed" into the TO section of an email. I dont know what im doing wrong but it doesnt work. Any suggestions?
foreach (Control c in Controls)
{
if (c is Label)
{
// Grab label
Label lbl = c as Label;
if (lbl.Text.Contains("closed"))
{
lbl.Text.Replace("closed", "");
}
}
}
Apparently you forgot to assign the modified text value, because Replace() method returns replaced text as return value:
lbl.Text = lbl.Text.Replace("closed", "");
But there might be more problems with your code, it's not very clear how is your problem related to emails.
Initially take your input (i.e. label list in a List)
List<string> TotalLabels = GetAllLabels();
for (int i = 0; i < TotalLabels.Count; i++)
{
if (TotalLabels[i].Contains("closed"))
{
TotalLabels.RemoveAt(i);
i--;
}
}
Now you have a final list which you wanted removing "closed".
Actually I'm facing problems with my textboxes and just to say that its my first Visual C# Application i do.
I just have many textboxes, around 14 textboxes and all i want is that after the user enter the values in each on i need this value to be saved in an array Temp[]
for example (
textbox1.text=1 so Temp[0]=1
textbox2.text=4 so Temp[1]=4
and etc....
I've included also a pic for my app:
so as you can see i the user must enter values for the first set and another values for the second set and i need to save the entered values in each set in an array to show later the union and the intersection of the sets.
Try this.
For 1st panel
int a=0;
foreach (TextBox tbx in Panel1.Controls.OfType<TextBox>())
{
Temp1[a]= tbx.text ;
a++;
}
For 2nd Panel
a=0;
foreach (TextBox tbx in Panel2.Controls.OfType<TextBox>())
{
Temp2[a]= tbx.text ;
a++;
}
Edit: You have to define 1st set of textboxes in panel1 and 2nd set in panel2.
I am developing a program wth 30 text boxes and 30 check boxes next to them. I want people to check names and then press the send button. The program then saves the names in a txt file with a true or false statement next to them, it then uploads the file to a ftp server for me analize.
The problem I am facing is that I don't want to write code for every text and check box to load and save it's value on the txt file.
If I name the text boxes something like tbox1;tbox2;tbox3 etc. How would use a loop to say write the value of tbox i + ; + cbox i on line i of thing.txt or vice versa?
Please any help would be grately apreciated because this will save me a lot of unnesacery code writing!
You should create a List<TextBox>, and populate it with your textboxes in the constructor.
You can then loop through the list and process the textboxes.
for (int i = 0; i <= count; i++)
{
TextBox textbox = (TextBox)Controls.Find(string.Format("tbox{0}", i),false).FirstOrDefault();
CheckBox checkbox = (CheckBox)Controls.Find(string.Format("cbox{0}", i),false).FirstOrDefault();
string s = textbox.Text + (checkbox.Checked ? "true" : "false");
}
You can loop over all the controls on your form and retrieve the values from them based on their type/name.
Loop through controls in your form/control and investigate name:
foreach (Control control in f.Controls)
{
if (control is TextBox)
{
//Investigate and do your thing
}
}
Assuming this is ASP.NET, you could use something like this:
StringBuilder sb = new StringBuilder();
for(int i = 1; i < 30; i++){
TextBox tb = FindControl("TextBox" + i);
Checkbox cb = FindControl("CheckBox" + i);
sb.AppendFormat("TextBox{0}={1}; {2}", i, tb.Text, cb.Checked);
}
string result = sb.ToString();
// Now write 'result' to your text file.