I had Added Button Controls dynamically in window form,now i want to add different event to every button control.
Here is my code of adding button dynamically from database.
private void GetButtonDynamically()
{
SqlConnection conn = GetConnection();
conn.Open();
using (conn)
{
SqlCommand cmd = new SqlCommand("Select MenuName from tblMainMenu",conn);
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
Button mybutton = new Button();
mybutton.Location = new Point(x, y + 54);
y += 54;
mybutton.Height = 44;
mybutton.Width = 231;
mybutton.BackColor = Color.Gainsboro;
mybutton.ForeColor = Color.Black;
mybutton.Text = reader["MenuName"].ToString();
mybutton.Name = reader["MenuName"].ToString();
mybutton.Font = new Font("Georgia", 12);
Controls.Add(mybutton);
mybutton.Click+= new EventHandler(mybutton_Click);
}
conn.Close();
}
}
Now the problem i am facing is it generate same Event for every button that is created dynamically, and i want different method for every button
Here Is Click Event
private void mybutton_Click(object sender, EventArgs e)
{
MessageBox.Show("Button is Clicked");
}
You can add a "AccessibleName" for your button while creating it. In your case inside your while loop and get the accessible name in button click event and apply a switch case or loop to differentiate it. sample code
int x = 10; int y = 10;
for (int i = 1; i < 5; i++)
{
Button mybutton = new Button();
mybutton.Location = new Point(x, y + 54);
y += 54;
mybutton.Height = 44;
mybutton.Width = 231;
mybutton.BackColor = Color.Gainsboro;
mybutton.ForeColor = Color.Black;
mybutton.Text = i + "MenuName".ToString();
mybutton.Name = i + "MenuName".ToString();
mybutton.AccessibleName = i.ToString();
mybutton.Font = new Font("Georgia", 12);
Controls.Add(mybutton);
mybutton.Click += new EventHandler(mybutton_Click);
}
In Button click modify like this
private void mybutton_Click(object sender, EventArgs e)
{
Button cb = (Button)sender;
string strName = cb.AccessibleName;
switch (strName)
{
case "1":
MessageBox.Show("Button 1 is Clicked");
break;
case "2":
MessageBox.Show("Button 2 is Clicked");
break;
case "3":
MessageBox.Show("Button 3 is Clicked");
break;
default:
break;
}
}
I think it can help you:
private void Form1_Load(object sender, EventArgs e)
{
int y = 0;
for (int i = 0; i < 10; i++)
{
Button mybutton = new Button();
mybutton.Location = new Point(0, y + 10);
y += 54;
mybutton.Height = 44;
mybutton.Width = 231;
mybutton.BackColor = Color.Gainsboro;
mybutton.ForeColor = Color.Black;
mybutton.Text = "a "+i.ToString();
mybutton.Name = "b" + i.ToString();
mybutton.Font = new Font("Georgia", 12);
switch (i)// define your condition
{
case 1:
mybutton.Click += new EventHandler(mybutton_Click);
break;
case 2:
mybutton.Click += new EventHandler(mybutton_1_Click);
break;
default:
break;
}
Controls.Add(mybutton);
}
}
private void mybutton_Click(object sender, EventArgs e)
{
MessageBox.Show("Button 1 is Clicked");
}
private void mybutton_1_Click(object sender, EventArgs e)
{
MessageBox.Show("Button 2 is Clicked");
}
Related
I have array of buttons, and array of labels:
Label[] labels = new Label[10];
Button[] but = new Button[10];
While clicking the other button I want to dynamically create new button and new label from the array, i also want the but[i] to change the tex of labels[i]:
private void button1_Click(object sender, EventArgs e)
{
labels[i] = new Label();
labels[i].Location = new System.Drawing.Point(0, 15+a);
labels[i].Parent = panel1;
labels[i].Text = "Sample text";
labels[i].Size = new System.Drawing.Size(155, 51);
labels[i].BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
a = labels[i].Height + labels[i].Top;
but[i] = new Button();
but[i].Text = "-";
but[i].Location = new System.Drawing.Point(0, labels[i].Height + labels[i].Top);
but[i].Parent = panel1;
but[i].Size = new System.Drawing.Size(155, 10);
but[i].Click += new System.EventHandler(but_Click);
i++;
}
private void but[i]_Click(object sender, EventArgs e)
{
labels[i].Text = "Changed Text";
}
But apparently I can't put an array in an event handler, how should I do it then?
One way to do this is to make your method return a handler instead of being a handler:
private EventHandler but_Click(int i)
{
return (s, e) => labels[i].Text = "Changed Text";
}
And use it like:
but[i].Click += but_Click(i);
Or do it inline:
but[i].Click += (s, ea) => labels[i].Text = "Changed Text";
What's happening in either of these is some compiler magic to capture the i variable. It's equivalent to this (which is also a valid, if verbose, way to do it):
class MyWrapper {
private int i;
public MyWrapper(int i) {
this.i = i;
}
public void TheHandler(object sender, EventArgs e) {
// TODO: capture the object that owns `labels` also, or this won't work.
labels[i].Text = "Changed Text";
}
}
//call with
but[i].Click += new EventHandler(new MyWrapper(i).TheHandler);
You could add the array index to the button as Tag property, and then pull it back out in but_Click.
So, add
but[i].Tag = i;
to the button creation. And then change the event handler:
private void but_Click(object sender, EventArgs e)
{
int buttonIndex = (int)((Button)sender).Tag;
labels[buttonIndex].Text = "Changed Text";
}
Or put the event handler inline:
but[i].Click += (s,e) => { label[i].Text = "Changed Text"; }
Or another option using the Tag property, add:
but[i].Tag = label[i];
...
private void but_Click(object sender, EventArgs e)
{
Label label = (Label)((Button)sender).Tag;
label.Text = "Changed Text";
}
Advantage of this approach is you're not relying on keeping arrays in synch after the initial creation of the controls.
I guess this is self-explaining:
public void SomeMehthod()
{
Button btn1 = new Button();
Button btn2 = new Button();
Button btn3 = new Button();
// Your button-array
Button[] btns = new Button[]
{
btn1,
btn2,
btn3
};
foreach(Button btn in btns)
{
// For each button setup the same method to fire on click
btn.Click += new EventHandler(ButtonClicked);
}
}
private void ButtonClicked(Object sender, EventArgs e)
{
// This will fire on any button from the array
// You can switch on the name, or location or anything else
switch((sender as Button).Name)
{
case "btn1":
// Do something
break;
case "btn2":
// Do something
break;
case "btn3":
// Do something
break;
}
}
Or if your array is accessible globaly:
Button[] btns = new Button[5];
Label[] lbls = new Label[5];
private void ButtonClicked(Object sender, EventArgs e)
{
Button clicked = sender as Button;
int indexOfButton = btns.ToList().IndexOf(clicked);
// ..IndexOf() returns -1 if nothign is found
if(indexOfButton > 0)
{
lbls[indexOfButton].DoWhatYouWant...
}
}
private void button1_Click(object sender, EventArgs e)
{
PictureBox dynamicPicture1 = new PictureBox();
dynamicPicture1.Tag = i;
dynamicPicture1.Location = new Point(x, y);
dynamicPicture1.Name = "pictureBox" + i;
dynamicPicture1.Size = new System.Drawing.Size(30, 27);
dynamicPicture1.ImageLocation =
"C:\\Users\\Newfolder\\Downloads\\x`enter code here`ryrvc.jpg";
panel1.Controls.Add(dynamicPicture1);
}
Try this updated code.
private void button1_Click(object sender, EventArgs e)
{
int s = 4;
int x = 0;
int y = 0;
for (int i = 0; i < s; i++)
{
if (i == 0)
{
x = 38;
y = 60;
}
else
{
y += 50;
}
PictureBox dynamicPicture1 = new PictureBox();
dynamicPicture1.Tag = i;
dynamicPicture1.Location = new Point(x, y);
dynamicPicture1.Name = "pictureBox" + i;
dynamicPicture1.Size = new System.Drawing.Size(30, 27);
dynamicPicture1.ImageLocation = #"C:\Users\nxa00960\Downloads\abc.jpg";
panel1.Controls.Add(dynamicPicture1);
dynamicPicture1.Click += dynamicPicture1_Click;
}
}
void dynamicPicture1_Click(object sender, EventArgs e)
{
var pictureBox = sender as PictureBox;
switch (pictureBox.Name)
{
case "pictureBox0":
//do something
break;
case "pictureBox1":
//do something
break;
case "pictureBox2":
//do something
break;
case "pictureBox3":
//do something
break;
default:
break;
}
}
You should put the Method name of your event handler:
dynamicPicture1.Click += dynamicPicture1_Click; //note the name here
And define the event handler somewhere:
void dynamicPicture1_Click(object sender, EventArgs e) {
throw new NotImplementedException(); //default not implemented
}
The name of the event handler must match each other...
I have a window form where I am creating a list of Checkboxes. The number of checkboxes created are based upon how many items are returned from the database. I've been able to create the checkboxes; however, I am not sure how to add event handlers for these checkboxes. For example, I'd like to add an OnCheckedChanged or CheckStateChanged event. How can I add these events? Also, I would appreciate any other suggestion. I am a total newbie to programming.
private void Form1_Load(object sender, EventArgs e)
{
CheckBoxes = new CheckBox[listGroup.Count()];
for (int i = 0; i < listGroup.Count(); i++)
{
CheckBoxes[i] = new CheckBox();
CheckBoxes[i].Text = listGroup.ElementAt(i).GroupName;
CheckBoxes[i].Name = "txt" + listGroup.ElementAt(i).GroupName.Replace(' ', '_');
CheckBoxes[i].CheckedChanged += new EventHandler(CheckBoxes[i]+"_CheckedChanged");
CheckBoxes[i].Width = 200;
if (i == 0)
{
CheckBoxes[i].Location = new System.Drawing.Point(5, 10);
}
else if (i == 1)
{
CheckBoxes[i].Location = new System.Drawing.Point(5, 40);
}
else if (i == 2)
{
CheckBoxes[i].Location = new System.Drawing.Point(5, 80);
}
this.Controls.Add(CheckBoxes[i]);
}
}
private void Form1_Load(object sender, EventArgs e)
{
//...
CheckBoxes[i].CheckedChanged += checkBoxes_CheckedChanged;
CheckBoxes[i].CheckStateChanged += checkBoxes_CheckStateChanged;
}
void checkBoxes_CheckedChanged(object sender, EventArgs e)
{ //do stuff when checked changed }
void checkBoxes_CheckStateChanged(object sender, EventArgs e)
{ //do stuff when check state changed }
Note: this will give identical event handling for all of your checkboxes.
If you want to do different things for different textboxes, you have to name the eventhandler differently and define that eventhandler.
A more efficient way to set the location of your checkboxes
for (int i = 0; i < listGroup.Count(); i++)
{
CheckBoxes[i] = new CheckBox();
CheckBoxes[i].Text = listGroup.ElementAt(i).GroupName;
CheckBoxes[i].Name = "txt" + listGroup.ElementAt(i).GroupName.Replace(' ', '_');
CheckBoxes[i].CheckedChanged += new EventHandler(CheckBoxes[i] + "_CheckedChanged");
CheckBoxes[i].Width = 200;
//set location based on index of i
CheckBoxes[i].Location = new System.Drawing.Point(5, 10 + (i * 30));
this.Controls.Add(CheckBoxes[i]);
}
private void LoadNewCheckboxes()
{
dynamic listGroupCount = 10;
List<System.Windows.Forms.CheckBox> CheckBoxes = new List<System.Windows.Forms.CheckBox>();
for (int i = 0; i <= listGroupCount - 1; i++)
{
System.Windows.Forms.CheckBox chkbox = new System.Windows.Forms.CheckBox();
chkbox.Text = i.ToString();
//listGroup.ElementAt(i).GroupName
chkbox.Name = "txt" + i.ToString();
//listGroup.ElementAt(i).GroupName.Replace(" "c, "_"c)
chkbox.CheckedChanged += new EventHandler(chkbox_CheckedChanged);
chkbox.CheckStateChanged += new EventHandler(chkbox_CheckStateChanged);
chkbox.Width = 200;
chkbox.AutoSize = true;
this.Controls.Add(chkbox);
CheckBoxes.Add(chkbox);
if (i == 0)
{
chkbox.Location = new System.Drawing.Point(5, 10);
}
else
{
chkbox.Location = new System.Drawing.Point(5, (CheckBoxes[i - 1].Top + CheckBoxes[i - 1].Height + 10));
}
}
}
private void chkbox_CheckedChanged(object sender, EventArgs e)
{
System.Windows.Forms.CheckBox chkbox = (System.Windows.Forms.CheckBox)sender;
if (chkbox != null)
{
//do somthing
Debug.WriteLine("chkbox_CheckedChanged");
Debug.WriteLine(chkbox.Text);
Debug.WriteLine(chkbox.Checked.ToString());
Debug.WriteLine(chkbox.Name.ToString());
}
}
private void chkbox_CheckStateChanged(object sender, EventArgs e)
{
System.Windows.Forms.CheckBox chkbox = (System.Windows.Forms.CheckBox)sender;
if (chkbox != null)
{
//do somthing
Debug.WriteLine("chkbox_CheckStateChanged");
Debug.WriteLine(chkbox.Text);
Debug.WriteLine(chkbox.Checked.ToString());
Debug.WriteLine(chkbox.Name.ToString());
}
}
I want to create click event on buttons, (2 Buttons are creating during runtime)
I am using this to create buttons:
private void Form1_Load(object sender, EventArgs e)
{
for (int k = 0; k < 2; k++)
{
Button Btn = new Button();
Btn.Name = "btn" + k;
Btn.Location = new System.Drawing.Point(20 + (k *110), 60 + (20 * j) * 2);
Btn.Size = new System.Drawing.Size(90, 30);
if (k == 0)
Btn.Text = "Back";
else
Btn.Text = "Calculate";
this.Controls.Add(Btn);
}
}
Thanks in Advance.
Enhance your loop like this:
for (int k = 0; k < 2; k++)
{
Button Btn = new Button();
Btn.Name = "btn" + k;
Btn.Location = new System.Drawing.Point(20 + (k *110), 60 + (20 * j) * 2);
Btn.Size = new System.Drawing.Size(90, 30);
if (k == 0)
Btn.Text = "Back";
else
Btn.Text = "Calculate";
Btn.Click += button_Click; // <-- This is where it happens!
this.Controls.Add(Btn);
}
Then add the event handler:
private void button_Click(object sender, EventArgs e)
{
Button btn = sender as Button;
if (btn.Name.Equals("..."))
{
}
else
{
}
}
Please note that within the event handler you need to decide which button has been pressed by looking at the Name property.
Simply use:
Btn.Click += button1_Click;
private void button1_Click(object sender, EventArgs e)
{
}
Like this
btn1.Click += new EventHandler(this.btn1_Click);
Btn.Click += Btn_Click;
void Btn_Click(object sender, EventArgs e)
{
throw new NotImplementedException();
}
in VS you can type Btn.Click += the press tab twice and it will generate the method for you.
3 problems in my WPF(window phone) simple project. I have spent lot of time by solving it but no specific result found..
In my cs file I have Created bunch of dynamic buttons...I crated with for loop and set tags for each dynamic button.
My cs File code is here.
private void Grid_View_Btn_1_Click(object sender, System.Windows.RoutedEventArgs e)
{
//Grid ButtonsAddition
Dispatcher.BeginInvoke(() =>
{
string[] Trade = new string[] { "Portfolio Display", "Trade Idea Entry", "Trade Idea Monitor", "Historical Performance", "Intraday Performance", "Stock Performance" };
StackPanel panel = new StackPanel();
panel.Orientation = System.Windows.Controls.Orientation.Vertical;
//panel.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
//panel.VerticalAlignment = System.Windows.VerticalAlignment.Top;
int i;
for (i = 0; i < Trade.Length; i++)
{
Button btn = new Button() { Content = Trade[i] };
btn.Margin = new Thickness(0, -10, 0, -10);
var brush = new ImageBrush();
brush.ImageSource = new BitmapImage(new Uri("C:/Users/HafizArslan/Documents/Visual Studio 2012/Projects/AimPass/AimPass/Images/tabbar_btn_blue.png", UriKind.Relative));
btn.Background = brush;
btn.Width = 190;
btn.Height = 75;
btn.FontSize = 14;
btn.FontWeight = light;
btn.FontStretch = Fill;
btn.HorizontalAlignment = HorizontalAlignment.Center;
btn.VerticalAlignment = System.Windows.VerticalAlignment.Stretch;
// btn.CornerRadius = new CornerRadius(15);
btn.BorderThickness = new Thickness(1, 1, 1, 1);
btn.Tag = i.ToString();
btn.Click += new RoutedEventHandler(abc_click);
panel.Children.Add(btn);
}
grid.Children.Add(panel);
});
}
private void abc_click(object sender, EventArgs e)
{
}
There are 6 buttons creted.
the problem is I want to perform different actions with button...I have set Tags but I dont know how can I access an actions with buttons Tag..?
I mean I want something like this...!!
private void abc_click(object sender, EventArgs e)
{
// If(btn.Tag==1)
{
//Some Code Here
}
else
if(btn.Tag==2) {
//Perform other Function
}
} Etc.....?
and other problem is I have made a image brush..Assign exact path of image...for every created button background....But Image is not attached...
Kindly tell me about these 2 problems...
You have sender in handler, you can type cast sender to button and access Tag property from it:
private void abc_click(object sender, EventArgs e)
{
Button button = (Button)sender;
if(Convert.ToInt32(button.Tag) == 1)
{
.....
}
}
In your for loop, you can associate handler to the button.
Such as:
Button btn = new Button() { Content = Trade[i] };
btn.Margin = new Thickness(0, -10, 0, -10);
if(<something>)
btn.Click += YourEventHandler1;
if(<something2>)
btn.Click += YourEventHandler2;
If you want to access tag property, you need to cast the sender to Button, as so:
private void abc_click(object sender, EventArgs e)
{
var btn = (Button)sender;
}
you should go with this
var tag=((sender as Button).Tag).ToString();
////now use a switch
Switch(tag)
{
case "1":
//Action
break;
case "2":
//Acrion
break;
//more cases
}
hope this helps.
if for all created buttons the event is same then One approach could be to get the tag in the event like this
int tag=Convert.ToInt32((sender as Button).Tag);
now use a switch
switch(tag)
{
case 1:
//Action
break;
case 2:
//Acrion
break;
//more cases
}
hope this helps.