I was wondering how to go about doing something such as this:
I need to create a Form with a specific number of buttons based on an integer value representing the number of buttons needed, then give them their own specific names so that each can have their own unique event handlers.
A real example I can think of doing this would be the Windows log-in screen, where the number of controls created is based on the number of users and whether there is a Guest account or not. How do you think that they programmed that?
Thank you.
for (int i = 0; i < 5; i++)
{
Button newButton = new Button();
newButton.Name = "button" + i.ToString();
newButton.Text = "Button #" + i.ToString();
newButton.Location = new Point(32, i * 32);
newButton.Click += new EventHandler(button1_Click);
this.Controls.Add(newButton);
}
private void button1_Click(object sender, EventArgs e)
{
if (((Button)sender).Name == "button0")
MessageBox.Show("Button 0");
else if (((Button)sender).Name == "button1")
MessageBox.Show("Button 1");
}
Somehow you have to define the names of all the buttons. I would suggest you to create a new string array and write the button names inside, and then use them in buttons creation loop:
//do the same length as the for loop below:
string[] buttonNames = { "button1", "button2", "button3", "button4", "button5" };
for (int i = 0; i < buttonNames.Lenght; i++)
{
Button newButton = new Button();
newButton.Name = "button" + i.ToString();
newButton.Text = buttonNames[i]; //each button will now get its own name from array
newButton.Location = new Point(32, i * 32);
newbutton.Size = new Size(25,100); //maybe you can set different sizes too (especially for X axes)
newButton.Click += new EventHandler(buttons_Click);
this.Controls.Add(newButton);
}
private void buttons_Click(object sender, EventArgs e)
{
Button btn = sender as Button
MessageBox.Show("You clicked button: " + btn.Text + ".");
}
Related
Here is my code so far where I have a numericupdown item named numericUpDown and button. Once the user selects a number when they press the button it dynamically created the fields.
private void createPerson_Click(object sender, EventArgs e)
{
Label[] person_Name = new Label[(int)this.numericUpDown.Value];
TextBox[] person_txtinput = new TextBox[(int)this.numericUpDown.Value];
for (int i = 0; i < this.numericUpDown.Value; i++)
{
//create person name label
Person_Name[i] = new Label();
Person_Name[i].Location = new System.Drawing.Point(20, 114 + i * 25);
Person_Name[i].Size = new System.Drawing.Size(120, 15);
Person_Name[i].Text = (i + 1).ToString() + #")" + "Person Name:";
this.Controls.Add(Person_Name[i]);
//create person name textbox
PersonNameTxtInput[i] = new TextBox();
PersonNameTxtInput[i].Location = new System.Drawing.Point(140, 114 + i * 25);
PersonNameTxtInput[i].Size = new System.Drawing.Size(125, 20);
this.Controls.Add(PersonNameTxtInput[i]);
}
}
private void save_Click(object sender, EventArgs e)
{
for (int i = 0; j < this.numericUpDown.Value; i++)
{
MessageBox.Show("" + PersonNameTxtInput[i].Text);
}
}
My question is, how can I get all the values from the textboxes depending on how many fields are created by the user when the save button is pressed?
I have tried using the code within the save button listener however how can i make Label[] person_Name = new Label[(int)this.numericUpDown.Value]; a global variable so i can access it within the save button for loop.
Well, I don't know exactly why you are doing this in this particular way and I must admit it doesn't seem very effective, but you could just do what Ryan_L suggested and iterate through this.Controls like this
for(int i = 0; i < this.Controls.Count; i++)
{
if(this.Controls[i] is TextBox) //skip buttons and labels
{
MessageBox.Show("" + this.Controls[i].Text);
}
}
Now, regarding your question how to define a global variable so you can access it within the save button for loop...just define the two arrays outside of the createPerson_Click event like this:
Label[] person_Name;
TextBox[] person_txtinput;
private void button1_Click(object sender, EventArgs e)
{
person_Name = new Label[(int)this.numericUpDown.Value];
person_txtinput = new TextBox[(int)this.numericUpDown.Value];
//the rest of the code
}
Hope this helps. However, you might want to reconsider your entire approach.
Label[] l1 = new Label[30];
DataTable dt = ConsoleApp2.CitiesDB.getCities(this.region);
foreach(DataRow row in dt.Rows)
{
count++;
string city = row.Field<string>("city");
l1[count] = new Label();
l1[count].Location = new System.Drawing.Point(x,y);
l1[count].Size = new Size(140, 80);
l1[count].Font = new System.Drawing.Font("Century Gothic", 8.5F);
l1[count].Text = city;
x = x + 260;
this.Controls.Add(l1[count]);
this.Refresh();
if(count == 4 || count %4 ==0)
{
y = y + 150;
x = 40;
}
//l1[count].Click += new EventHandler(l1_click);
}
So i made a dynamic labels (each label is a city name). how can i make each label clickable? i have a register form - what i want is if user clicks on "new york" then in the "city" textbox it will appear. the way with the EventHandler doesnt works for me);. what can i do?
what i mean in code that doesnt work:
protected void l1_click(object sender, EventArgs e)
{
RegisterForm register = new RegisterForm(username,email,password,address,phone);
register.state.Text = region;
register.city.Text = l1[count].Text;
register.Show();
}
thanks (:
Assign one click event for each label (dynamically created):
l1[count].Click += l1_click;
In the one click event use the sender argument to see which label was clicked on:
protected void l1_click(object sender, EventArgs e)
{
Label lbl = (Label)sender;
MessageBox.Show(lbl.Text);
}
How to create buttons dynamically after user input in C# (Visual Studio).
There is a text-box to enter how many buttons user wants?
Then my target is to create buttons below the input field as the user wants
then how can I get id's of that buttons?
private void button1_Click(object sender, EventArgs e)
{
List<Button> buttons = new List<Button>();
for (int i = 0; i < n; i++)
{
this.Controls.Add(buttons[i]);
}
}
Here I first added an event handler to the textbox, which is called whenever the text value is changed. The value is converted to the int value and then is used in a for loop statement. You can set your button's potion to the desired value using location property. Using tag or name property you can assign a unique value to your buttons. I hope the code helps.
Look at the code below :
private void Form1_Load(object sender, EventArgs e)
{
textBox1.TextChanged += textBox1_TextChanged;
}
void textBox1_TextChanged(object sender, EventArgs e)
{
var txtBox = sender as TextBox;
if (txtBox == null) return;
var count = Convert.ToInt16(txtBox.Text);
//
var xPosition = 0;
for (var i = 1; i <= count; i++)
{
var button = new Button
{
Tag = string.Format("Btn{0}", i),
Text = string.Format("Button{0}",i),
Location = new Point(xPosition, 0)
};
xPosition = xPosition + 100;
Controls.Add(button);
}
When you are creating Control(in your case Buttons) you can give them Name property. It will be very good if that name will be unique.
var btn = new Button();
btn.Name = "MyBtn";
btn.Text = "Our Button";
this.Controls.Add(btn);
For creation of N buttons you just need to put this in a Loop with N iterations and set btn.Name to something like "Name"+SomeNumber.
To set the Position of the Buttons to below the input you should set btn.Left and btn.Top to the corresponding coordinates.
Then when you need to work with generated Control/Button you can do search by that Name in the following way:
var btn = (Button)this.Controls.Find("MyBtn", true).First();
and do whatever you want with that Control/Button.
But in this case there is some danger as I am not checking if there was found any control with that name. If you write incorrect Name this will throw exception on .First().
In the program, by clicking button2, is created a table and imlemented data insertion. Also created textbox and login button, which is used for reading data from this textbox. When the login button is pressed, next actions should happen:
MessageBox should display some text;
login.Text should be changed;
table, which was created by clicking button2 should be deleted.
I dont know actually how to get access from login.click event handler to table in button2. I guess it should be done somehow by using EventArgs, but i dont understand how. Also I thought about creating some variable outside button2 handler scope, and use it later, but I guess its a bad practise.
Please,tell me how to solve this, or maybe its just wrong decision to create windows forms components such a way? if it`s so, then how to?) here is my code:
private void button2_Click(object sender, EventArgs e)
{
label1.Hide();
label2.Hide();
textBox1.Hide();
textBox2.Hide();
button2.Hide();
int user_count = Int32.Parse(textBox2.Text);
int file_count = Int32.Parse(textBox1.Text);
DataGridView T = new DataGridView();
T.Dock = DockStyle.Top;
T.AutoResizeColumns();
T.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
T.ColumnCount = file_count + 1;
T.RowCount = user_count + 1;
Controls.Add(T);
Controller_cs c = new Controller_cs(user_count, file_count);
for(int i = 1; i < T.RowCount; i++)
{
T.Rows[i].Cells[0].Value = c.user_name_insertion(i-1);
}
for (int i = 1; i < T.ColumnCount; i++)
{
T.Rows[0].Cells[i].Value = c.file_name_insertion(i - 1);
}
for(int i = 1; i < T.RowCount;i++)
{
for(int j = 1; j < T.ColumnCount;j++)
{
T.Rows[i].Cells[j].Value = c.rigts_insertion(j-1,i-1);
}
}
Label l = new Label();
l.Text = "Name";
l.Left = 20;
l.Top = 180;
Controls.Add(l);
TextBox username = new TextBox();
username.Left = 20;
username.Top = 210;
Controls.Add(username);
Button login = new Button();
login.Text = "Enter";
login.Left = 130;
login.Top = 175;
login.Click += login_handler;
Controls.Add(login);
}
private void login_handler(object sender, EventArgs e)
{
Button b = (Button)sender;
if (b.Text == "Enter")
{
b.Text = "Exit";
MessageBox.Show("Enter is done");
}
else
{
b.Text = "Enter";
MessageBox.Show("Quit is done");
}
}
I'm making a game with 6 dynamic buttons as "btn" at the top row and other 6 "lamp buttons" on a buttom row.
Player clicks on a top row button and text displayed in a bottom row button after clicking on it.
As soon as all the lamp buttons are full with text, I want a submit buttom to appear.
I tried to make for and foreach for my lamp buttons and it didn't help. Plese help!
here is a code:
public partial class Game : System.Web.UI.Page
{
protected void Page_Init(object sender, EventArgs e)
{
for (int i = 0; i < 6; i++)
{
Button btnLamp = new Button();
btnLamp.ID = "btnLamp" + i.ToString();
btnLamp.Click += btnLamp_Click;
this.Panel1.Controls.Add(btnLamp);
}
LiteralControl ltBreak = new LiteralControl();
ltBreak.Text = "<br/><br/>";
Panel1.Controls.Add(ltBreak);
Panel1.DataBind();
for (int i = 0; i < 6; i++)
{
Button btn = new Button();
btn.ID = "btn" + i.ToString();
btn.Text = "btn" + i.ToString();
btn.Click += btn_Click;
this.Panel2.Controls.Add(btn);
}
Panel2.DataBind();
}
void btn_Click(object sender, EventArgs e)
{
Button clickedbutton = (Button)sender;
string btn_cliked = clickedbutton.ID;
for (int i = 0; i <5 ; i++)
{
((Button)FindControl(("btn" + i.ToString()))).BackColor = System.Drawing.Color.LightSteelBlue;
}
clickedbutton.BackColor = System.Drawing.Color.Beige;
Session["clickedbutton"] = clickedbutton;
}
void btnLamp_Click(object sender, EventArgs e)
{
Button clickedbutton = (Button)sender;
string btnLamp_cliked = clickedbutton.ID;
((Button)FindControl(((Button)Session["clickedbutton"]).ID)).Enabled = false;
for (int i = 0; i < 5; i++)
{
if (((Button)Session["clickedbutton"]).Text.ToString() == ((Button)FindControl("btnLamp" + i)).Text)
{
((Button)FindControl("btnLamp" + i)).Text = "";
}
}
clickedbutton.Text = ((Button)Session["clickedbutton"]).Text.ToString();
}
This sort of stuff is best handled client side in javascript.
Attach a handler to the onchange event of your inputs and figure out inside it if
all inputs have value. Then show your button on page (should be present but hidden - display:none).
If none of the above makes any sense i suggest to do some research on web programming. Figure out the purpose of server code (C# in your case) versus html and javascript. Then come back with questions if needed