Click event for dynamically created array of buttons - c#

In my application i have array of buttons created dynamically.I am trying to raise an onclick event for those buttons and change the text of the button which i click.I tried the below code for this but its not working.How can i do this?.Any suggesions?
Code:
for (int i = 0; i < 5; i++)
{
lbl = new Button[5];
lbl[i] = new Button();
lbl[i].Text = "hi";
lbl[i].Width = 30;
lbl[i].Click += new EventHandler(lbl_click);
//lbl[i].CssClass = "label";
div1.Controls.Add(lbl[i]);
}
Click Event:
protected void lbl_click(object sender, EventArgs e)
{
Button[] lbl = sender as button[];
lbl[i].Text = "clicked";
}

You are recreating the array of buttons in your event handler, but this array is not populated with the buttons created before. It is empty and will give you a null reference exception if you try to use an element of this array (null.Text, it will never work).
The sender object instead, represent the button that the user has clicked.
protected void lbl_click(object sender, EventArgs e)
{
Button lbl = sender as Button;
lbl.Text = "clicked";
}
Also, if you need to know which specific button has been clicked then I suggest you to add something to differentiate between them at creation time:
For example use the name property:
Button[] lbl = new Button[5];
for(int i = 0; i< 5; i++)
{
....
lbl[i].Name = "Button_" + i.ToString();
....
}
Notice that I have moved the array declaration and initialization outside the loop that create every single element of the array (the actual button).

Related

Bind Event Handlers within a loop

I'm trying to bind events to dynamically created menu item's click event that is created in a for loop. When I click the menu item, the code executes, but it's with the last value of "x" within the loop. This is the code:
for(int x = 1; x < 3; x++)
{
MenuItem mi = new MenuItem("Get");
ContextMenu cm = new ContextMenu();
mi.Click += (s, e) => { GetClick(x); };
cm.MenuItems.Add(mi);
Button btn = this.Controls.Find("btnGet" + x.ToString(), true).FirstOrDefault() as Button;
btn.ContextMenu = cm;
}
private void GetClick(int intGetItem)
{
//Previous code...
GetItem(intGetItem);
}
The issue is when I debug the GetClick Method, intGetItem is always equal to 3 no matter which button I use. Any help is appreciated!
You need to assign x to a local variable and use this in your expression:
var y = x;
mi.Click += (s, e) => { GetClick(y); };
here is an explanation: https://blogs.msdn.microsoft.com/ericlippert/2009/11/12/closing-over-the-loop-variable-considered-harmful/
You can't define the parameters of an event when you register for it. Instead you should pass on the parameters that the menu item will supply.
mi.Click += GetClick;
And change your event to get the standard Click parameters:
private void GetClick(object sender, EventArgs e)
{
if (sender == menu1) {...

Dynamically create buttons in c# by user at runtime

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().

c# - how can I handle the click event of controls created dynamically within a loop

I'm looking for some advice on how to add click event handlers to labels that have been created created dynamically within a loop.
I've searched for click event handlers on dynamically created controls but this always comes back with single controls that aren't within an array.
example of code:
//create an array of 16 labels
Label[] label = new Label[16];
//loop through the array of labels
for (int i = 0; i < label.Length; i++)
{
label[i] = new Label(); //create new label
label[i].Name = "lbl" + i.ToString(); //give the label a name
label[i].Text = "label " + i.ToString(); //give the label text
}
Any help and advice on this would be great, thanks!
Add a handler:
label[i].Click += HandleLabelClick;
void HandleLabelClick(object sender, EventArgs e)
{
// ...
}
Note that you can determine which label was clicked by using the sender argument:
void HandleLabelClick(object sender, EventArgs e)
{
var label = (Label) sender;
if (label.Text == "this or that") { /* ... */ }
}

How do I add click events to all buttons that have names starting with a certain string in C#?

I am writing a simple calculator script for my C# programming class. It will of course have buttons 0-9 that will update the output textbox to add the number of whatever button is clicked. My problem right now that is I would rather not have to have 10 different click events in my script. I would rather have a loop that cycles through the buttons that will add the same click event to each one and then decide what number to add to the output based on the button.
So right now, I have a click event for the "1" button which is this...
private void btnNum1_Click(object sender, EventArgs e)
{
txtOutput.Text = Convert.ToString(txtOutput.Text + "1");
}
This works fine, but, again, I would rather not have to do this 10 times. How can I create a loop that prevents this?
The button names are btnNum1, btnNum2, btnNum3, etc.
Assuming the button text is just "1", "2" etc you could do this:
private void btnNum_Click(object sender, EventArgs e)
{
var button = sender as Button
txtOutput.Text += button.Content.ToString();
}
Then just apply this event to all the buttons.
Also note you don't need Convert.ToString() as what you are trying to convert is already a string. Using += also cleans up your code a bit.
You could do this to wire-up all of the events in one go:
for (var n = 0; n <= 9; n++)
{
var btn =
this
.Controls
.Find("btnNum" + n.ToString(), false)
.Cast<Button>()
.First();
var digit = n;
btn.Click += (s, e) =>
{
txtOutput.Text = digit.ToString();
};
}
You could enumerate the children controls of your Form/Control, look the type of controls which are type of Button and the name StartWith 'btnNum', with each of these buttons, add a Click event address to btnNum_Click().
Say if all your buttons are contained in a Panel named 'pnlButtons', you could loop all the children like this.
foreach (var control in pnlButtons.Controls)
{
if(control.GetType() == typeof(Button))
{
var button = control as Button;
if (button .Name.StartWith('btnNum'))
{
button.Click += btnNum_Click;
}
}
}
You can use the "Tag" property of the Button control and make an array of Buttons to subscribe to the same event. See sample below:
void InitializeButtons()
{
Button btnNum1 = new Button();
btnNum1.Text = "1";
btnNum1.Tag = 1;
//Button 2..8 goes here
Button btnNum9 = new Button();
btnNum9.Text = "9";
btnNum9.Tag = 9;
Button[] buttons = new Button[]{
btnNum1, btnNum2, btnNum3, btnNum4, btnNum5, btnNum6, btnNum7, btnNum8, btnNum9
};
for (int i = 0; i < buttons.Length; i++)
{
buttons[i].Click += Button_Click;
}
}
void Button_Click(object sender, EventArgs e)
{
Button button = (Button)sender;
int value = (int)button.Tag;
//Do something with value
}
Assuming WinForms, you can recursively search for buttons that start with "btnNum" and wire them up to a common handler like this:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.Load += Form1_Load;
}
void Form1_Load(object sender, EventArgs e)
{
FindButtons(this);
}
private void FindButtons(Control ctl)
{
foreach(Control ctrl in ctl.Controls)
{
if (ctrl.Name.StartsWith("btnNum") && (ctrl is Button))
{
Button btn = (Button)ctrl;
btn.Click += btn_Click;
}
else if(ctrl.HasChildren)
{
FindButtons(ctrl);
}
}
}
private void btn_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
txtOutput.Text = Convert.ToString(txtOutput.Text + btn.Text);
}
}

Eventhandler for multiple generated buttons C#

I have generated multiple buttons when I click on btnStart and I'd like to use booleans for each button to become true when it gets clicked so I can check the clicked buttons later on but I only know how to use the same event for every button
This is what I use to create the buttons (I left some unnecessary things out)
for (int i = 0; i < 5; i++) //I use this to horizontally generate buttons
{
for (int j = 0; j < 4; j++) //vertically generate buttons
{
Button btnNew = new Button();
btnNew.Name = "btnFlag" + i;
btnNew.Click += new EventHandler(btnNew_Click);
Controls.Add(btnNew);
aButtons.Add(btnNew); //this is a list I use to set random bgImages
}
}
Now when I click on btnNew it would do all the code set for the event btnNew_Click but I can't use btnFlag1_Click because it doesn't exist, does anyone know a way to create booleans for every buttons and set one to true when a specific button is being clicked
Like: when btnFlag1 gets clicked, turn boolean btn1 to true
and so on ..
Thank you in advance
When you are looping in your for statement you are assigning same event to all your methods.But the sender paramater of your method contains the reference of the button which is calling the specific event.
you can bind all the buttons to same event
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 4; j++)
{
Button btnNew = new Button();
btnNew.Name = "btnFlag" + i;
btnNew.Click += new EventHandler(btnNew_Click);
}
}
Then inside the button click new event you can select your specific sender and perform specific actions
public void btnNew_Click(object sender, ButtonEventArgs e)
{
Button b = sender as Button;
if( b.Name == "btnFlag0" )
{
//logic for your 1st btn
}
//.... repeat the same logic for others
}
You can use the sender argument in the event handler, which in fact is the specific Button which was clicked:
private void btnNew_Click(Object sender, EventArgs e)
{
Button btn = sender as Button;
string name = btn.Name;
}

Categories

Resources