Get Value Dynamic Textbox in C# - 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
}
}
}

Related

Windows form receive text input

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.

Removing or Hide dynamically created linklabels and labels

Background
I create a set of linklabel and label controls using a loop that uses data from a database as there content (Text).
Question
How do I then remove or change there visibility?
What I would Like to Happen?
On a button click event, I would like all of the link's and linklabel's text properties to be set to either null, or their visibility properties to be set as false.
Code
private void getInfoStationID()
{
//SQL Connection Stuff
for (int i = 0; i <= rowCount - 1; i++)
{
LinkLabel Linklabel = new LinkLabel();
Linklabel.Text = ds.Tables[0].Rows[i] ["code"].ToString();
Linklabel.Height = 15;
Linklabel.Width = 50;
Linklabel.AutoSize = true;
Linklabel.Location = new Point(10, (i + 1) * 30);
tabControl1.TabPages[0].Controls.Add(Linklabel);
// Add an event handler to do something when the links are clicked.
Linklabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked);
Label label1 = new Label();
label1.Text = ds.Tables[0].Rows[i]["name"].ToString();
label1.Height = 15;
label1.Width = 70;
label1.Location = new Point(100, (i + 1) * 30);
tabControl1.TabPages[0].Controls.Add(label1);
Label label3 = new Label();
label3.Text = ds.Tables[0].Rows[i]["toc"].ToString();
label3.Height = 15;
label3.Width = 50;
label3.Location = new Point(240, (i + 1) * 30);
tabControl1.TabPages[0].Controls.Add(label3);
}
}
private void clearAllBtn_Click(object sender, EventArgs e)
{
//Would like this to clear all previously drawn labels and linklabels
}
Simply add the dynamic controls to a List so you have a quick reference to them:
// out at CLASS/FORM level:
private List<Control> MyControls = new List<Control>();
// ... some method ...
for (int i = 0; i <= rowCount - 1; i++)
{
LinkLabel Linklabel = new LinkLabel();
MyControls.Add(Linklabel);
// ... rest of your code ...
Label label1 = new Label();
MyControls.Add(label1);
// ... rest of your code ...
Label label3 = new Label();
MyControls.Add(label3);
// ... rest of your code ...
}
Now you can use that List from somewhere else:
private void clearAllBtn_Click(object sender, EventArgs e)
{
foreach(Control ctl in MyControls)
{
ctl.Visible = false; // or something else
}
}
*Don't forget to dispose of those controls and empty the list if you decide to create a new set of dynamic controls. If you want to completely get rid of them:
private void clearAllBtn_Click(object sender, EventArgs e)
{
foreach(Control ctl in MyControls)
{
ctl.Dispose();
}
MyControls.Clear();
}
You can loop through all controls on a certain tabpage. You could use a open generic function to make the code nice and clean. Like this:
private void HideControls<TControl>(Control parentControl)
where TControl : Control
{
var controls = parentControl.Controls.OfType<TControl>();
foreach (var control in controls)
{
control.Visible = false;
}
}
And use it like this:
private void button1_Click(object sender, EventArgs e)
{
this.HideControls<Label>(tabControl1.TabPages[0]);
this.HideControls<LinkLabel>(tabControl1.TabPages[0]);
}
You could even refactor this to a nice extension method:
public static class ControlExtensions
{
public static void HideControlsOfType<TControl>(this Control parentControl)
where TControl : Control
{
var controls = parentControl.Controls.OfType<TControl>();
foreach (var control in controls)
{
control.Visible = false;
}
}
}
and use like:
this.tabControl1.TabPages[0].HideControlsOfType<Label>();

How to create many labels and textboxes dynamically depending on the value of an integer variable?

Is there any way to dynamically create and display 'n' Labels with 'n' corresponding Textboxs when we know value of 'n' after for example, clicking "Display" button.
Let me know if anything make you don't understand my question. Thank you!
I am working with VS C# Express 2010 Windows Form.
I would create a user control which holds a Label and a Text Box in it and simply create instances of that user control 'n' times. If you want to know a better way to do it and use properties to get access to the values of Label and Text Box from the user control, please let me know.
Simple way to do it would be:
int n = 4; // Or whatever value - n has to be global so that the event handler can access it
private void btnDisplay_Click(object sender, EventArgs e)
{
TextBox[] textBoxes = new TextBox[n];
Label[] labels = new Label[n];
for (int i = 0; i < n; i++)
{
textBoxes[i] = new TextBox();
// Here you can modify the value of the textbox which is at textBoxes[i]
labels[i] = new Label();
// Here you can modify the value of the label which is at labels[i]
}
// This adds the controls to the form (you will need to specify thier co-ordinates etc. first)
for (int i = 0; i < n; i++)
{
this.Controls.Add(textBoxes[i]);
this.Controls.Add(labels[i]);
}
}
The code above assumes that you have a button btnDisplay and it has a onClick event assigned to btnDisplay_Click event handler. You also need to know the value of n and need a way of figuring out where to place all controls. Controls should have a width and height specified as well.
To do it using a User Control simply do this.
Okay, first of all go and create a new user control and put a text box and label in it.
Lets say they are called txtSomeTextBox and lblSomeLabel. In the code behind add this code:
public string GetTextBoxValue()
{
return this.txtSomeTextBox.Text;
}
public string GetLabelValue()
{
return this.lblSomeLabel.Text;
}
public void SetTextBoxValue(string newText)
{
this.txtSomeTextBox.Text = newText;
}
public void SetLabelValue(string newText)
{
this.lblSomeLabel.Text = newText;
}
Now the code to generate the user control will look like this (MyUserControl is the name you have give to your user control):
private void btnDisplay_Click(object sender, EventArgs e)
{
MyUserControl[] controls = new MyUserControl[n];
for (int i = 0; i < n; i++)
{
controls[i] = new MyUserControl();
controls[i].setTextBoxValue("some value to display in text");
controls[i].setLabelValue("some value to display in label");
// Now if you write controls[i].getTextBoxValue() it will return "some value to display in text" and controls[i].getLabelValue() will return "some value to display in label". These value will also be displayed in the user control.
}
// This adds the controls to the form (you will need to specify thier co-ordinates etc. first)
for (int i = 0; i < n; i++)
{
this.Controls.Add(controls[i]);
}
}
Of course you can create more methods in the usercontrol to access properties and set them. Or simply if you have to access a lot, just put in these two variables and you can access the textbox and label directly:
public TextBox myTextBox;
public Label myLabel;
In the constructor of the user control do this:
myTextBox = this.txtSomeTextBox;
myLabel = this.lblSomeLabel;
Then in your program if you want to modify the text value of either just do this.
control[i].myTextBox.Text = "some random text"; // Same applies to myLabel
Hope it helped :)
Here is a simple example that should let you keep going add somethink that would act as a placeholder to your winform can be TableLayoutPanel
and then just add controls to it
for ( int i = 0; i < COUNT; i++ ) {
Label lblTitle = new Label();
lblTitle.Text = i+"Your Text";
youlayOut.Controls.Add( lblTitle, 0, i );
TextBox txtValue = new TextBox();
youlayOut.Controls.Add( txtValue, 2, i );
}
Suppose you have a button that when pressed sets n to 5, you could then generate labels and textboxes on your form like so.
var n = 5;
for (int i = 0; i < n; i++)
{
//Create label
Label label = new Label();
label.Text = String.Format("Label {0}", i);
//Position label on screen
label.Left = 10;
label.Top = (i + 1) * 20;
//Create textbox
TextBox textBox = new TextBox();
//Position textbox on screen
textBox.Left = 120;
textBox.Top = (i + 1) * 20;
//Add controls to form
this.Controls.Add(label);
this.Controls.Add(textBox);
}
This will not only add them to the form but position them decently as well.
You can try this:
int cleft = 1;
intaleft = 1;
private void button2_Click(object sender, EventArgs e)
{
TextBox txt = new TextBox();
this.Controls.Add(txt);
txt.Top = cleft * 40;
txt.Size = new Size(200, 16);
txt.Left = 150;
cleft = cleft + 1;
Label lbl = new Label();
this.Controls.Add(lbl);
lbl.Top = aleft * 40;
lbl.Size = new Size(100, 16);
lbl.ForeColor = Color.Blue;
lbl.Text = "BoxNo/CardNo";
lbl.Left = 70;
aleft = aleft + 1;
return;
}
private void btd_Click(object sender, EventArgs e)
{
//Here you Delete Text Box One By One(int ix for Text Box)
for (int ix = this.Controls.Count - 2; ix >= 0; ix--)
//Here you Delete Lable One By One(int ix for Lable)
for (int x = this.Controls.Count - 2; x >= 0; x--)
{
if (this.Controls[ix] is TextBox)
this.Controls[ix].Dispose();
if (this.Controls[x] is Label)
this.Controls[x].Dispose();
return;
}
}

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.

How to change properties of a Control that is in List<UIControl> without using Loop?

I have the following code where a click event will dynamically create additional Canvas to the WrapPanel, and each Canvas contains a TextBox and a Button. Once the Button on one Canvas is click, TextBox.Text and Button.Content change from "Foo" to "Jesus".
The below code works, but it's not ideal. Because each property Change ("Foo" to "Jesus), I have to run a loop. I have to run two loops just to change the text on the TextBox and Button. Is there a direct way to change the Properties other then a Loop? My actually application contains 30+ controls in a Canvas, I don't want to run 30+ loops each time just to change some text.
List<Canvas> cvList = new List<Canvas>();
List<TextBox> tbList = new List<TextBox>();
List<Button> FooList = new List<Button>();
WrapPanel wp = new WrapPanel();
private void createbtn1_Click(object sender, RoutedEventArgs e)
{
Canvas cv = new Canvas();
StackPanel sp = new StackPanel();
TextBox tb = new TextBox();
Button Foo = new Button();
sp.Orientation = Orientation.Vertical;
sp.Children.Add(tb);
sp.Children.Add(Foo);
cv.Children.Add(sp);
wp.Children.Add(cv);
cvList.Add(cv);
tbList.Add(tb);
FooList.Add(Foo);
cv.Width = 100;
cv.Height = 100;
tb.Text = "#" + (cvList.IndexOf(cv)+1);
tb.Width = 50;
tb.Height = 30;
Foo.Content = "Foo";
Foo.Click += destroy_Click;
}
private void Foo_Click(object sender, RoutedEventArgs e)
{
Button b = sender as Button;
var bIndex = FooList.IndexOf(b);
foreach (TextBox t in tbList)
{
if (tbList.IndexOf(t) == bIndex)
{
t.Text = "Jesus";
}
}
foreach (Button f in FooList)
{
if (FooList.IndexOf(t) == bIndex)
{
t.Content = "Jesus";
}
}
}
Just access the text boxes by index and set the content of the button directly:
if(bIndex < tbList.Count && bIndex != -1)
tbList[bIndex].Text = "Jesus";
if(b != null && bIndex != -1)
b.Content = "Jesus";
why can't you just get the item at the index and set that items text:
tbList[bindex].Text="Jesus";
As for setting the buttons content, you already have the button from the click event, so just use that:
b.Content = "Jesus";
You current code just loops through each item in the list and gets the index of the item and sees if it is the index you want. Accessing by the indexer of the list directly will give you what you want.
You will probably want to do some error checking, but that is not currently done in your existing code either.
Some info on using indexers from MSDN

Categories