Windows form receive text input - c#

Hey guys/girls I got myself stuck and I was hoping I could get some help with it. simply said I'm trying to make a soccerpool on windows form. Because the player can put in as many team's as he/she wants I put the code that makes the betting panels in a (for)loop with the text as 0. very handy if I say so myself but now I can't retrieve the correct input from the user or without breaking the loop. any idea's?
for (int i = 0; i < hometable.Rows.Count; i++)
{
DataRow dataRowHome = hometable.Rows[i];
DataRow dataRowAway = awayTable.Rows[i];
Label lblHomeTeam = new Label();
Label lblAwayTeam = new Label();
TextBox txtHomePred = new TextBox();
TextBox txtAwayPred = new TextBox();
lblHomeTeam.TextAlign = ContentAlignment.BottomRight;
lblHomeTeam.Text = dataRowHome["TeamName"].ToString();
lblHomeTeam.Location = new Point(15, txtHomePred.Bottom + (i * 30));
lblHomeTeam.AutoSize = true;
txtHomePred.Text = "0";
txtHomePred.Location = new Point(lblHomeTeam.Width, lblHomeTeam.Top - 3);
txtHomePred.Width = 40;
txtAwayPred.Text = "0";
txtAwayPred.Location = new Point(txtHomePred.Width + lblHomeTeam.Width, txtHomePred.Top);
txtAwayPred.Width = 40;
lblAwayTeam.Text = dataRowAway["TeamName"].ToString();
lblAwayTeam.Location = new Point(txtHomePred.Width + lblHomeTeam.Width + txtAwayPred.Width, txtHomePred.Top + 3);
lblAwayTeam.AutoSize = true;
pnlPredCard.Controls.Add(lblHomeTeam);
pnlPredCard.Controls.Add(txtHomePred);
pnlPredCard.Controls.Add(txtAwayPred);
pnlPredCard.Controls.Add(lblAwayTeam);
So what my end goal is, is recieving the input from the user validating them and then storing them in a database.

Well, depending on how the user activates an event that requires the reading of the TextBox you have a few possible solutions.
Here is one where the TextBox (read all TextBox's) waits for enter:
private void Form_Load(object sender, EventArgs e)
{
while(someLoop)
{
TextBox theTextBox = new TextBox();
theTextBox.Name = "SomeUniqeName";//Maybe team name?
theTextBox.KeyUp += TheTextBox_KeyUp;
}
}
private void TheTextBox_KeyUp(object sender, KeyEventArgs e)
{
if ( e.KeyCode == Keys.Enter )
{
TextBox textbox = (TextBox) sender;//Get the textbox
//Just an example
listOfTeams.First( r => r.TeamName == textbox.Name )
.SomeOtherProperty = textbox.Text;
}
}
The textbox's are now identifiable by their name and all have an event. No matter how many you make.
If you will store the data later with 1 click of a button (and another loop) this solution might be better:
string[] Teams = { "teamA", "teamB", "teamC" };
private void Form1_Load(object sender, EventArgs e)
{
for ( int i = 0; i < Teams.Length; i++ )
{
TextBox theTextBox = new TextBox();
//Prefix the name so we know this is a betting textbox
//Add the 'name' (teams[i] in this case) to find it
theTextBox.Name = "ThePrefix" + Teams[i];
}
}
private void someButton_Click(object sender, EventArgs e)
{
//We want all betting textbox's here but also by team name
for ( int i = 0; i < Teams.Length; i++ )
{
//Because we set the name, we can now find it with linq
TextBox textBox = (TextBox) this.Controls.Cast<Control>()
.FirstOrDefault( row => row.Name == "ThePrefix" + Teams[i] );
}
}
This way each textbox is identifiable and won't conflict with other textbox's (because of 'ThePrefix'). This is essentially the other way around from the first method as it looks for the textbox based on data rather than data based on textbox name.

Related

C# delete dynamically added textbox and move all other textboxes down

I have really been struggling with this question for a long time.
I add a textbox and a button on tab press . I put text inside the textboxes:
Now, my question, how do I remove the textbox next to the button I click and move all the textboxes down, so I won't get any open space. If I press on the button next to the 7th textbox, I want it to look like this:
here's my code:
private void Form1_Load(object sender, EventArgs e)
{
//creates a textbox(t0) and a button(b0) on load
TextBox t0 = new TextBox();
t0.Name = "t0";
t0.Location = new Point(16, 12);
t0.Width = 200;
t0.PreviewKeyDown += new PreviewKeyDownEventHandler(PreviewKeyDown);
Button b0 = new Button();
b0.TabStop = false;
b0.Text = "x";
b0.Location = new Point(216, 11);
b0.Size = new System.Drawing.Size(20, 22);
b0.Click += new EventHandler(buttonclicked);
panel1.Controls.Add(t0);
panel1.Controls.Add(b0);
}
private new void PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
//if I press tab in the last textbox it creates a new textbox(t + amount of textboxes) and button(b + amount of textboxes)
if (e.KeyData == Keys.Tab)
{
int counter2 = 0;
foreach (TextBox box in panel1.Controls.OfType<TextBox>())
{
counter2++;
}
counter2 = counter2 - 1;
string Name = "t" + Convert.ToString(counter2);
counter2++;
foreach (TextBox box in panel1.Controls.OfType<TextBox>())
{
if (Name == box.Name && box.Focused)
{
TextBox t0 = new TextBox();
Button b0 = new Button();
t0.Location = new Point(16, 12 + counter - panel1.VerticalScroll.Value);
t0.Width = 200;
t0.Name = "t" + Convert.ToString(counter2);
t0.PreviewKeyDown += new PreviewKeyDownEventHandler(PreviewKeyDown);
b0.TabStop = false;
b0.Text = "x";
b0.Name = "b" + Convert.ToString(counter2);
b0.Location = new Point(216, 11 + counter - panel1.VerticalScroll.Value);
b0.Size = new System.Drawing.Size(20, 22);
b0.Click += new EventHandler(buttonclicked);
panel1.Controls.Add(t0);
panel1.Controls.Add(b0);
counter = counter + 25;
}
}
}
}
private void buttonclicked(object sender, EventArgs e)
{
//Remove the textbox next to it.
}
Any help is appreciated
I suggest you use a TableLayoutPanel. Set the GrowStyle on the TableLayoutPanel to AddRows or AddColumns and then you can add/remove controls to it and it will resize automatically. Set the height of each row to a number a little bigger than the height of the textbox. Set the column widths to a value so the textbox and the button can fit in them. You need 2 columns in it.
You do not need to set the location of the controls to a static location. They will be handled by the TableLayoutPanel for you.
Here is how you can add new controls to it.
yourTableLayoutPanel.Controls.Add(yourTextbox1, 0 /* Column Index */, 0 /* Row index */);

Get Value Dynamic Textbox in C#

I made dynamic textboxes and keep it List
private void ConvertButton_Click(object sender, EventArgs e)
{
List<TextBox> textBoxes = new List<TextBox>();
foreach (Control item in this.Controls)
{
if (item is TextBox)
{
TextBox txt = item as TextBox;
textBoxes.Add(txt);
}
}
}
I get all of textboxes value but i have a problem. For examples; if user add 3 label like (A,B,C) and add Textboxes for them like (labelA has 2,labelB has 3,labelC has 1) and textboxes get value like array (textboxes[0] has value).The problem is i dont know which label has which value.
I added Textbox just like this:
private void addNewTextbox(object sender, EventArgs e)
{
Button button = (Button)sender;
List<TextBox> textBoxes = button.Tag as List<TextBox>;
if (textBoxes == null)
button.Tag = textBoxes = new List<TextBox>();
TextBox textBox = new TextBox();
textBoxes.Add(textBox);
textBox.Location = new Point(90 * textBoxes.Count, button.Top);
textBox.Size = new Size(50, 50);
this.Controls.Add(textBox);
}
I try to show screen for example;
LabelA-->Textbox1 , Textbox2
</br>
labelB -->Textbox3
</br>
LabelC --> Textbox4 , Textbox5 , TextBox6
Every control that is added has a Name property. Use this property to link the different controls together. For example (and you should come up with your own naming convention), you could do this:
LabelA --> TextboxA1, TextboxA2
LabelB --> TextboxB1
LabelC --> TextboxC1, TextboxC2, TextboxC3
If you wish to have a more complete (i.e. complex) solution, you could:
Create your own control that inherits from TextBox
Add a property for the name of the associated Label control
Set this property when a new control is instantiated
Label[] labelArray = new Label[10];
for (int i = 0; i < labelNumber; i++)
{
labelArray[i] = new Label();
labelArray[i].Text = states[i] + "-->";
this.Controls.Add(labelArray[i]);
labelArray[i].Top = 100 + i * 30;
labelArray[i].Left = 10;
labelArray[i].Width = 30;
}
i did label-created just like this.labelnumber is how many label user wants.#interceptwind
I am trying very hard to understand your question, I guess you are trying to link the user-created textboxes to specific labels? Forgive me if I am completely wrong. How about structure your code to something like this:
Note: Edited with OP's new code
Dictionary<Int, List<TextBox>> label_Textboxes_Dict = new Dictionary<Int, List<TextBox>>();
List<Label> labelArray = new List<Label>(); //I suggest use list as you don't know the array size beforehand
void addLabel(int labelNumber)
{
int currentLabelArrayCount = labelArray.count; //So that users can add multiple times
for (int i = currentLabelArrayCount; i < currentLabelArrayCount +labelNumber; i++)
{
labelArray.Add(new Label());
labelArray[i].Text = states[i] + "-->";
this.Controls.Add(labelArray[i]);
labelArray[i].Top = 100 + i * 30;
labelArray[i].Left = 10;
labelArray[i].Width = 30;
label_Textboxes_Dict.Add(i, new List<TextBox>());
}
}
void addTextBoxForLabel(int labelNum)
{
TextBox t1 = new TextBox();
TextBox t2 = new TextBox();
//etc...
if (label_Textboxes_Dict.ContainsKey(labelNum))
{
label_Textboxes_Dict[labelNum].Add(t1);
label_Textboxes_Dict[labelNum].Add(t2);
}
}
void doSomethingForAllTextboxesOfLabel(int labelNum)
{
List<TextBox> listOfTextBoxes;
if(label_Textboxes_Dict.TryGetValue(labelNum, out listOfTextBoxes))
{
foreach(TextBox tb in listOfTextBoxes)
{
//do your stuff
}
}
}

Dynamic Textbox event TextChanged is not firing

I have a problem with a Dynamic Textbox event. I got other dynamic textbox with their textchanged events, the others work good, but this one never get into the event, the property AutoPostBack = true, EnabledViewState too, EnabledViewTheming too, and it's into an UpdatePanel and I create a Dynamic Trigger.
This is my code:
TextBox DescUnit = new TextBox();
DescUnit.ID = "DescUnit_txt" + (No).ToString();
DescUnit.Text = "0.0";
DescUnit.TextChanged += new EventHandler(DescUnit_TextChanged);
DescUnit.AutoPostBack = true;
DescUnit.EnableViewState = true;
DescUnit.EnableTheming = true;
Trgr = new PostBackTrigger();
Trgr.ControlID = DescUnit.ID;
UpdatePanel1.Triggers.Add(Trgr);
Table.Rows[i - 1].Cells[3].Controls.Add(DescUnit);
And this is the code of my Event
protected void DescUnit_TextChanged(object sender, EventArgs e)
{
Descuento_Row.Visible = true;
int i = 1;
foreach (HtmlTableRow Row in Tab.Rows)
{
if (Row.ID != null && String.Compare(Row.ID.Substring(0, 6), "TRDet_") == 0)
{
Detalle = (HtmlTable)(Row.Cells[0].Controls[0]);
if (sender.Equals(Detalle.Rows[1].Cells[3].Controls[0]))
{
TextBox Cantidad = new TextBox();
Clonar(Tab.Rows[i].Cells[1].Controls[0], Cantidad);
TextBox Precio = new TextBox();
Clonar(Tab.Rows[i].Cells[4].Controls[0], Precio);
TextBox DescUnit = new TextBox();
Clonar(Detalle.Rows[1].Cells[3].Controls[0], DescUnit);
TextBox ImpDesc = new TextBox();
Clonar(Detalle.Rows[2].Cells[4].Controls[0], ImpDesc);
ImpDesc_txt.Text = ((Convert.ToDouble(ImpDesc_txt.Text) - Convert.ToDouble(ImpDesc.Text)) + (Convert.ToDouble((Convert.ToDouble(DescUnit.Text) / 100)) * (Convert.ToDouble(Precio.Text) * Convert.ToInt32(Cantidad.Text)))).ToString();
ImpDesc.Text = (Convert.ToDouble((Convert.ToDouble(DescUnit.Text) / 100)) * (Convert.ToDouble(Precio.Text) * Convert.ToInt32(Cantidad.Text))).ToString();
Detalle.Rows[2].Cells[4].Controls.Clear();
Detalle.Rows[2].Cells[4].Controls.Add(ImpDesc);
}
i = i + 2;
}
}
}
But never get into it. Can anyone help me?
When ever we are creating controls in ASP.Net the controls can be create on form load or after it. But if you want events of the controls. you should initialize it in onInit Method. Then It will work properly.
If suppose I want to create dynamic textbox and its event. and want to add it in panel
Please refer following code.
protected override void OnInit(EventArgs e)
{
TextBox t = new TextBox();
t.ID = "t01";
t.TextChanged += t_TextChanged;
t.AutoPostBack = true;
Panel1.Controls.Add(t);
}
protected void t_TextChanged(object sender, EventArgs e)
{
}
Also please be sure that ID of the control is properly. Must interger,underscore and alphanumeric. ex t001, t_1 etc
But should not space.

C# Get text from a textbox that is made at runtime

Hello I am making a program that has 2 textboxes and 2 buttons
When I press the add button then it will make 2 new textboxes using this code :
private void ADD_ROW_Click(object sender, EventArgs e)
{
//Make the NEW_TEXTBOX_1
HOW_FAR += 1;
TextBox NEW_TEXTBOX_1 = new TextBox();
NEW_TEXTBOX_1.Name = "NAME_TEXTBOX_" + HOW_FAR.ToString();
//Set NEW_TEXTBOX_1 font
NEW_TEXTBOX_1.Font = new Font("Segoe Print", 9);
NEW_TEXTBOX_1.Font = new Font(NEW_TEXTBOX_1.Font, FontStyle.Bold);
//Set pos and size and then create it.
NEW_TEXTBOX_1.Location = new System.Drawing.Point(16, 71 + (35 * HOW_FAR));
NEW_TEXTBOX_1.Size = new System.Drawing.Size(178, 29);
this.Controls.Add(NEW_TEXTBOX_1);
//Make the PRICE_TEXTBOX_
TextBox NEW_TEXTBOX_2 = new TextBox();
NEW_TEXTBOX_2.Name = "PRICE_TEXTBOX_" + HOW_FAR.ToString();
//Set NEW_TEXTBOX font
NEW_TEXTBOX_2.Font = new Font("Segoe Print", 9);
NEW_TEXTBOX_2.Font = new Font(NEW_TEXTBOX_2.Font, FontStyle.Bold);
//Set pos and size and then create it.
NEW_TEXTBOX_2.Location = new System.Drawing.Point(200, 71 + (35 * HOW_FAR));
NEW_TEXTBOX_2.Size = new System.Drawing.Size(89, 29);
this.Controls.Add(NEW_TEXTBOX_2);
//Change pos of the add button
ADD_ROW.Location = new System.Drawing.Point(295, 71 + (35 * HOW_FAR));
this.Height = 349 + (35 * HOW_FAR);
this.Width = 352;
}
This works very well but now I want to get the text from a newly made textbox back how do I do this?
This doesn't work because it says : NAME_TEXTBOX_1 Does not exist in the current context.
private void button2_Click(object sender, EventArgs e)
{
string tmpStr = NAME_TEXTBOX_1.Text;
}
You need to move the variable declaration outside of the ADD_ROW_Click event handler so that it's accessible outside that block;
TextBox NEW_TEXTBOX_1;
private void ADD_ROW_Click(object sender, EventArgs e)
{
//Make the NEW_TEXTBOX_1
HOW_FAR += 1;
NEW_TEXTBOX_1 = new TextBox(); //remove "TextBox" since we declared it above
NEW_TEXTBOX_1.Name = "NAME_TEXTBOX_" + HOW_FAR.ToString();
//...
The alternative, and possibly better depending on the number of textboxes, is to add each TextBox you create into a List. You can then iterate that List from and find the TextBox you want. For example
List<TextBox> allTextBoxes = new List<TextBox>();
private void ADD_ROW_Click(object sender, EventArgs e)
{
//Make the NEW_TEXTBOX_1
HOW_FAR += 1;
TextBox NEW_TEXTBOX_1 = new TextBox();
//...fill out the properties
//add an identifier
NEW_TEXTBOX_1.Tag = 1;
allTextBoxes.Add(NEW_TEXTBOX_1);
}
Then when you want a particular TextBox
private void button2_Click(object sender, EventArgs e)
{
TextBox textBox1 = allTextBoxes.Where(x => x.Tag == 1).FirstOrDefault();
string tmpStr = "";
if(textBox1 != null)
tmpStr = textBox1.Text;
}
Alternatively, and especially if you're going to have a lot of TextBoxes, you could store them in a Dictionary as Corak suggested in the comments.
you're declaring NAME_TEXTBOX_1 within the ADD_ROW_Click method, which is why it isn't available within the button2_Cick method.
You can declare the textbox at the class level to access it in both places.
(You should work on renaming your variables too - e.g. TextBoxPrice)
One simple solution:
Make a private field called "NEW_TB" for example.
In your button2_Click(..) { string tmpStr = NEW_TB.Text; }
Add in your ADD_ROW_Click(..) method NEW_TB = NAME_TEXTBOX_1;
If I understood your question right, this should work.
Make global your textboxes:
TextBox NEW_TEXTBOX_1;
then initiate them in your method:
NEW_TEXTBOX_1 = new TextBox();
OMG Never mind sorry guys I found a good way :D
var text = (TextBox)this.Controls.Find("PRICE_TEXTBOX_1", true)[0];
text.Text = "PRO!";
This works pretty well :)

Linking dynamically created text boxes and labels

I created an array of of TextBoxes and an array of Labels. When the information is updated in the TextBox I want it to change the Labels. How would I be able to do this? Below is piece of my code. I have not created the EvenHandler that I think is the part I need help with. All in C# using windows application form.
textBoxes = new TextBox[value];
labels = new Label[value];
for (int i = 1; i < value; i++)
{
textBoxes[i] = new TextBox();
textBoxes[i].Location = new Point(30, ToBox.Bottom + (i * 43));
labels[i] = new Label();
labels[i].Location = new Point(TopBox3[i].Width + 140, TopBox3[i].Top +3);
textboxes[i].ValueChanged += new EventHandler(this.TextBox_ValueChanged) ;
this.Controls.Add(labels[i]);
this.Controls.Add(textBoxes[i]);
}
You can remember the index of the TextBox in the Tag property
textBoxes[i].Tag = i;
and then use this value in your eventhandler to get the corresponding label (assuming that you hold the labels array as a local variable)
protected void TextBox_ValueChanged(object sender, EventArgs e)
{
TextBox textbox = sender as TextBox;
if(textbox==null)
return;
int index = Convert.ToInt32(textbox.Tag);
if(index >= 0 && index < this.labels.Length)
{
Label label = this.labels[index];
/* ... */
}
}
You should write something like this:
private void textBox1_ValueChanged(object sender, EventArgs e)
{
TextBox changedTxt = sender as TextBox;
for (int i = 1; i < value; i++)
if (textBoxes[i] == changedTxt)
{
Label lblToChange = labeld[i];
lblToChange.Text = changedTxt.Text;
break;
}
}
In the method the TextBox whose text has changed is passed as "sender". You look into your array for it, so you identify the index "i" which can be used to access the corresponding Label and to set its text.
BTW as Tim said, the event is TextChanged, not ValueChanged. Furthermore be aware that the event is triggered for every change in the text, i.e. as soon as you press a key the label will be updated. If you prefer to update your labels only when the user has finished to enter its text Leave is the event you should use.

Categories