I'm using c#, and I have a project that instantiates a lot of PictureBox buttons. I also have all of the click,hover,mouseUp,mouseDown event methods programmed. How do I call a method from a string name so that I don't have to write all of them by hand? Thanks in advance, Carson
Dictionary<string, PictureBox> buttonList = new Dictionary<string,PictureBox>();
string buttonName = "button_file";
buttonList[buttonName].Click += new EventHandler(buttonName + "_click");
public void button_file_click(object sender, EventArgs e)
{
// do on click stuff here
}
if you set the Name property of button, you can so:
buttonList[buttonName].Name = buttonName;
buttonList[buttonName].Click += ButtonClick;
and only One metode hanle all buttons click but in accordance of their name:
public void ButtonClick(object sender, EventArgs e)
{
var btn = (Button)sender;
btn.Text = btn.Name; //only for demo
}
but you can completely write your own method:
buttonList[buttonName].Click += (s,e)=> clickEvent(buttonList[buttonName], buttonName);
this is a short lambda function which accepts the parameters accordingly of Click event singature and fire your custom function, the clickEvent:
public void clickEvent(Button thePressedButton, string nameOfPresedButton)
{
thePressedButton.Text = btn.nameOfPresedButton; //only for demo
}
From your sample code, I assume you want them all to call button_file_click.
In that case just set the eventhandler to that method:
buttonList[buttonName].Click += new EventHandler("button_file_click");
A method name isn't quite enough... you also need a class name... but assuming the method belongs to the current class (this) you can use Reflection to do this:
public void ExecuteMethod(string methodName)
{
var methodInfo = this.GetType().GetMethod(methodName);
methodInfo.Invoke(this, new [] {});
}
But you can't assign the above to an event because it is not the right delegate type; most event handlers require a sender and an EventArgs. So to make your code work you'd need a little more glue:
Dictionary<string, PictureBox> buttonList = new Dictionary<string,PictureBox>();
string buttonName = "button_file";
buttonList[buttonName].Click += GetHandler(buttonName + "_click");
public Action<object, EventArgs> GetHandler(string handlerName)
{
var methodInfo = this.GetType().GetMethod(handlerName, new Type[] {typeof(object), typeof(EventArgs)});
return new Action<object, EventArgs> (sender, eventArgs) => methodInfo.Invoke(this, new [] {sender, eventArgs});
}
The idea here is that GetHandler returns an Action with the right signature (accepting an object and an EventArgs, in that order), which is written as Action<object, EventArgs>. The GetHandler method uses reflection to find the right method in the current class, then creates a lambda expression that invokes the method via reflection, passing the arguments as an array.
The above is of course just an example... it would probably be better to store your delegates in a static dictionary that is computed when the page is loaded for the first time.
That being said, if you're looking for event handling flexibility based on a runtime parameter, a better approach is probably to use the Command event, which allows you to pass a string to the handler, which can then take a different action depending on the contents of the string. That way you can hardcode the handler reference but still softcode what it will do.
Dictionary<string, PictureBox> buttonList = new Dictionary<string,PictureBox>();
string buttonName = "button_file";
buttonList[buttonName].Command += buttonList_Command;
buttonList[buttonName].CommandName = buttonName;
protected void buttonList_Command(object sender, CommandEventArgs e)
{
switch (e.CommandName)
{
case buttonName:
//Do stuff for button_file
break;
case "Foo":
//Do stuff for some other button named foo
break;
default:
throw new InvalidOperationException();
}
}
You can use reflection to look up the method of a class by name and then create an event handler delegate using that method. For example:
void bindHandler(string buttonName)
{
string methodName = buttonName + "_click";
System.Reflection.MethodInfo m = this.GetType().GetMethods().FirstOrDefault(x => x.Name == buttonName + "_click");
PictureBox button = buttonList[buttonName];
Delegate handler = Delegate.CreateDelegate(typeof(EventHandler), this, m);
button.Click += (EventHandler)handler;
}
Fulling working code:
namespace WindowsFormsApp1Cs
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
MyClass c = new MyClass();
foreach (var item in c.buttonList)
{
this.Controls.Add(item.Value);
}
}
}
public class MyClass
{
public Dictionary<string, PictureBox> buttonList;
public delegate void MyClickHandler(object sender, EventArgs e);
public MyClass()
{
buttonList = new Dictionary<string, PictureBox>();
buttonList.Add("button_file_1", new PictureBox() { Width = 100, Height = 100, Name = "button_file_1", Anchor = AnchorStyles.Top | AnchorStyles.Left, Top = (buttonList.Count * 100) + 10, Left = 10, ImageLocation="0.jpg" });
buttonList.Add("button_file_2", new PictureBox() { Width = 100, Height = 100, Name = "button_file_2", Anchor = AnchorStyles.Top | AnchorStyles.Left, Top = (buttonList.Count * 100) + 10, Left = 10, ImageLocation = "0.jpg" });
buttonList.Add("button_file_3", new PictureBox() { Width = 100, Height = 100, Name = "button_file_3", Anchor = AnchorStyles.Top | AnchorStyles.Left, Top = (buttonList.Count * 100) + 10, Left = 10, ImageLocation = "0.jpg" });
foreach (var item in buttonList)
{
bindHandler(item.Key);
}
}
void bindHandler(string buttonName)
{
string methodName = buttonName + "_click";
System.Reflection.MethodInfo m = this.GetType().GetMethods().FirstOrDefault(x => x.Name == buttonName + "_click");
PictureBox button = buttonList[buttonName];
Delegate handler = Delegate.CreateDelegate(typeof(EventHandler), this, m);
button.Click += (EventHandler)handler;
}
public void button_file_1_click(object sender, EventArgs e)
{
Debug.WriteLine("button_file_1_click");
}
public void button_file_2_click(object sender, EventArgs e)
{
Debug.WriteLine("button_file_2_click");
}
public void button_file_3_click(object sender, EventArgs e)
{
Debug.WriteLine("button_file_3_click");
}
}
}
Related
This is the code.
For example purposes, NewButton will have the name "Add", the SubMenuButtonNamesList is a list of strings containing the names of the buttons that I will be creating, afterwards I wanted to add the handler to these buttons based on the methods found in the mainwindow, matched by their names.
I think I did it properly since the button does have this handler added, but when I click the button nothing happens, it should show me a messagebox saying "yes".
public void Add_Method(object sender, MouseButtonEventArgs e)
{
MessageBox.Show("Yes");
}
public MainWindow()
{
InitializeComponent();
//Create all sub-menu buttons
foreach (var element in SubMenuButtonNamesList)
{
Button NewButton = new Button()
{
Background = new SolidColorBrush(new Color { A = 100, R = 231, G = 233, B = 245 }),
FontFamily = new FontFamily("Century Gothic"),
Content = element,
FontSize = 14,
Height = 30,
Width = Double.NaN,
VerticalAlignment = VerticalAlignment.Center,
HorizontalAlignment = HorizontalAlignment.Center
};
NewButton.Name = element.Trim();
try
{
MethodInfo method = typeof(MainWindow).GetMethod(NewButton.Name + "_Method");
Delegate myDelegate = Delegate.CreateDelegate(typeof(MouseButtonEventHandler), this, method);
NewButton.MouseLeftButtonDown += (MouseButtonEventHandler)myDelegate;
}
catch (Exception e)
{
}
SubMenuButtonsList.Add(NewButton);
}
}
It appears the MouseLeftButtonDown event for Button (didn't check for anything else), if added this way will not fire, however if you do it for the Click event, it will fire properly, see below snippet of the modifications:
MethodInfo method = typeof(MainWindow).GetMethod(NewButton.Name + "_Method");
Delegate myDelegate = Delegate.CreateDelegate(typeof(RoutedEventHandler), this, method);
NewButton.Click += (RoutedEventHandler)myDelegate;
And the method:
public void Add_Method(object sender, RoutedEventArgs e)
{
MessageBox.Show("Yes");
}
I´m using WindowsForm and working with flat design. In the program there are 6 buttons, these buttons are made of a label and a panel. The label controls all the actions that the button can do. when i started writing the program i made one function for each button, now i like to use one function that controls all buttons. I have tried to make that work but I´m stuck and can´t find a way to solve it.
Been looking around at the forum for solutions but i think that i might not know what i´m looking for.
This is what i made so far.
Buttons[] cobra = new Buttons[5];
private class Buttons
{
private bool position;
private string name;
public bool Position
{
get { return position; }
set { position = value; }
}
public string Name
{
get { return name; }
set { name = value; }
}
}
private void SetButtons()
{
cobra[0].Name = "label3";
cobra[0].Position = false;
cobra[1].Name = "label4";
cobra[1].Position = false;
}
private void CheckStatusButtons(object import)
{
for (int i = 0; i < cobra.Length; i++)
{
}
}
private class ToggelFunction
{
private bool hawk;
public bool Hawk
{
get { return hawk; }
set { hawk = value; }
}
}
ToggelFunction tiger = new ToggelFunction();
private void label3_Click(object sender, EventArgs e)
{
if (tiger.Hawk == false)
{
button1.BackColor = Color.PaleGreen;
label3.Text = "ON";
if (myport.IsOpen)
{
send(new byte[] { 16, 128, 32, 16, 1 });
}
tiger.Hawk = true;
return;
}
if (tiger.Hawk == true)
{
button1.BackColor = Color.DarkSeaGreen;
label3.Text = "2";
if (myport.IsOpen)
{
send(new byte[] { 16, 128, 32, 8, 1 });
}
tiger.Hawk = false;
return;
}
}
"label3_Click" this is my function for button 1, all buttons look the same just different variables.
As I found on the forum, you can use object sender to i identify which button that made the click and from there use that in the function to make action.
So all buttons will use this functions, i´m not sure how to compare values in the if statement, if button 1 is click then it should check what values button 1 has.
My idea was to make a class "Buttons" and an array to store all the values of each button, it´s not completed yet. When a button is clicked it checks
with the array what values that button has and compare that in the function depending on what the action is. The first action would be to check if the button is on or off. If it´s off then it enters that if statement and there some actions will happen, change of color and the text, these values also have to be stored in the array i guess.
I have tried to compare the array with object sender, but i get some error saying that you can´t compare bool with object i think.
So i wonder if some one might have a solution or suggestions?
I have made a simple example of what i think you want to do. bare in mind this does not abide by all coding best practises but its not a mess either. You will need to put your safety null checks in.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public class ButtonVariables
{
public int value1 { get; set; }
public int value2 { get; set; }
}
Dictionary<string, ButtonVariables> bv = new Dictionary<string, ButtonVariables>();
private void ProcessClick(object sender, EventArgs e)
{
ButtonVariables vars = GetVariables(sender);
//Do stuff with your variable set here
}
private ButtonVariables GetVariables(object sender)
{
ButtonVariables returnValue = new ButtonVariables();
switch (((Button)sender).Name.ToLower())
{
case "buttona":
return bv["A"];
case "buttonb":
return bv["B"];
case "buttonc":
return bv["C"];
default:
break;
}
return null;
}
private void ButtonA_Click(object sender, EventArgs e)
{
ProcessClick(sender, e);
}
private void ButtonB_Click(object sender, EventArgs e)
{
ProcessClick(sender, e);
}
private void ButtonC_Click(object sender, EventArgs e)
{
ProcessClick(sender, e);
}
}
I've basically added two methods to handle your method. One to identify the button and get its related values from a dictionary that you will have to populate with your Buttons class. and one to carry out the logic.
EDIT
As requested in the comments here's an easy (but not the only way) to point your event listeners towards the same method.
Initially you need to set up with one button and double click it or do some other way to create the forms Button_Click() Event Method. At this point an event listener delegate has been added to your Form.Designer.cs File. Open that file and you will see something like this:
//
// ButtonA
//
this.ButtonA.Location = new System.Drawing.Point(12, 12);
this.ButtonA.Name = "ButtonA";
this.ButtonA.Size = new System.Drawing.Size(75, 23);
this.ButtonA.TabIndex = 0;
this.ButtonA.Text = "button1";
this.ButtonA.UseVisualStyleBackColor = true;
this.ButtonA.Click += new System.EventHandler(this.ButtonA_Click);
What you need to do is create your other buttons and add this code in for them with a change to the last line new System.EventHandler(this.ButtonA_Click); This line basically states which method to call when the ButtonA.Click event is invoked. At this point you can add what ever method you want (as long as you name is nicely for good convention). So your example would be this :
//
// ButtonA
//
this.ButtonA.Location = new System.Drawing.Point(12, 12);
this.ButtonA.Name = "ButtonA";
this.ButtonA.Size = new System.Drawing.Size(75, 23);
this.ButtonA.TabIndex = 0;
this.ButtonA.Text = "button1";
this.ButtonA.UseVisualStyleBackColor = true;
this.ButtonA.Click += new System.EventHandler(this.ProcessClick);
//
// ButtonB
//
this.ButtonB.Location = new System.Drawing.Point(12, 12);
this.ButtonB.Name = "ButtonB";
this.ButtonB.Size = new System.Drawing.Size(75, 23);
this.ButtonB.TabIndex = 0;
this.ButtonB.Text = "B";
this.ButtonB.UseVisualStyleBackColor = true;
this.ButtonB.Click += new System.EventHandler(this.ProcessClick);
//
// ButtonC
//
this.ButtonC.Location = new System.Drawing.Point(12, 12);
this.ButtonC.Name = "ButtonC";
this.ButtonC.Size = new System.Drawing.Size(75, 23);
this.ButtonC.TabIndex = 0;
this.ButtonC.Text = "C";
this.ButtonC.UseVisualStyleBackColor = true;
this.ButtonC.Click += new System.EventHandler(this.ProcessClick);
Remember you need to physically create the buttons on the form itself.
Lets say you have three labels and a panel for each label. You can add the event handler to all of them and whenever that event fires the event handler will use that label as the sender. To keep the panel associated with the label, you could add the panel to the label's tag property. Then, in the event handler you can then get the panel from the label.
label1.Click += label_Click;
label2.Click += label_Click;
label3.Click += label_Click;
label1.Tag = panel1;
label2.Tag = panel2;
label3.Tag = panel3;
In the event handler, just cast sender to Label and there you have your label object to do whatever you want with and like I said, the panel is in the Tag property. I did a little refactoring to your code to make it cleaner looking.
private void label_Click(object sender, EventArgs e)
{
// this is what itsme86 was suggesting in the comments
var label = (Label)sender;
var panel = (Panel)label.Tag;
label.BackColor = tiger.Hawk ? Color.DarkSeaGreen : Color.PaleGreen;
label.Text = tiger.Hawk ? "2" : "ON";
if (myport.IsOpen)
send(new byte[] { 16, 128, 32, 8, 1 });
tiger.Hawk = !tiger.Hawk;
}
Let me know if you have any questions about this.
So I was trying to send custom arguments to an event, but it never worked, I tried so many different methods, but I never got it to work,
So basically!
public void CreateEmojiList()
{
CreateAllEmojis();
int btnCount = 0;
foreach(Emoji emoji in emojiList)
{
Button btnEmoji = new Button();
btnEmoji.Size = new Size(40, 36);
btnEmoji.FlatStyle = FlatStyle.Flat;
btnEmoji.FlatAppearance.MouseDownBackColor = Color.Cyan;
btnEmoji.Cursor = Cursors.Hand;
btnEmoji.Font = new Font("Bahnschrift", 6.75f);
btnEmoji.Text = emoji.EmojiText;
btnEmoji.Top = (panel_main.Controls.OfType<Button>().Count<Button>() / 4) * (1 + btnEmoji.Height) + 6;
btnEmoji.Left = (btnEmoji.Width + 1) * btnCount + 6;
panel_main.Controls.Add(btnEmoji);
btnEmoji.Click += //What do I do here?
; btnCount++;
if (btnCount == 4)
btnCount = 0;
}
}
protected virtual void OnEmojiClick(EmojiClickEventArgs e)
{
if (this.EmojiClick != null)
EmojiClick(e);
}
this is the class I want to use to pass my arguments:
public class EmojiClickEventArgs : EventArgs
{
private string emojiText;
private string emojiName;
public EmojiClickEventArgs(string EmojiText, string EmojiName)
{
this.EmojiText = EmojiText;
this.EmojiName = EmojiName;
}
public string EmojiText { get { return emojiText; } set { emojiText = value; } }
public string EmojiName { get { return emojiName; } set { emojiName = value; } }
}
I want to get those two values from
emoji.EmojiText and emoji.EmojiName
You can take advantage of closures to "package up" the additional event data for each button's event handler. Just make sure not to close over the loop variable.
public void CreateEmojiList()
{
CreateAllEmojis();
int btnCount = 0;
foreach(Emoji emoji in emojiList)
{
Button btnEmoji = new Button();
btnEmoji.Size = new Size(40, 36);
btnEmoji.FlatStyle = FlatStyle.Flat;
btnEmoji.FlatAppearance.MouseDownBackColor = Color.Cyan;
btnEmoji.Cursor = Cursors.Hand;
btnEmoji.Font = new Font("Bahnschrift", 6.75f);
btnEmoji.Text = emoji.EmojiText;
btnEmoji.Top = (panel_main.Controls.OfType<Button>().Count<Button>() / 4) * (1 + btnEmoji.Height) + 6;
btnEmoji.Left = (btnEmoji.Width + 1) * btnCount + 6;
panel_main.Controls.Add(btnEmoji);
var emojiCopy = emoji; //don't close on the loop variable!
btnEmoji.Click += (sender,args) => OnEmojiClick(emojiCopy);
btnCount++;
if (btnCount == 4)
btnCount = 0;
}
}
protected virtual void OnEmojiClick(Emoji emoji)
{
//do something
}
One way is to inherit from Button and create a class called EmojiButton. You then declare a delegate that matches the signature of the your event handler. After that, declare an event using the delegate in the EmojiButton class, add property like EmojiText and EmojiName to the button subclass as well. Finally you need to link the button click event with your custom event. Whenever the button is clicked, raise your event and pass your arguments i.e. this.EmojiText, this.EmojiName.
Another way is to assign your Emoji objects to the Tag property. You can then write the event handler with the normal EventHandler signature (object sender, EventArgs e), and look at what the sender's Tag is. You then cast the Tag to an Emoji and access its properties.
The fastest solution that comes to my mind and that doesn't imply the definition of custom UserControl classes, the subclassing of Button and other similar practices is:
btnEmoji.Click += (sender, e) =>
{
Button b = (Button)sender;
// let's suppose that the button name corresponds to the emoji name
String emojiName = b.Name;
// let's suppose that the button tag contains the emoji text
String emojiText = (String)b.Tag;
Emoji_Clicked(sender, e, (new EmojiClickEventArgs(emojiText, emojiName)));
};
private void Emoji_Clicked(Object sender, EventArgs e, EmojiClickEventArgs ee)
{
// Your code...
}
First and foremost thing you need to define delegate ,then create an instance.
class Emojis
{
// public delegate void EmojiClickEventHandler(object sender,EventArgs args);
//public event EmojiEventHandler EmojiClicked;
//you can use above two lines or replace them instead below code.
public event EventHandler<EmojiClickEventArgs> EmojiClicked;
public void CreateEmojiList()
{
CreateAllEmojis();
int btnCount = 0;
//rest of the code
panel_main.Controls.Add(btnEmoji);
btnEmoji.Click += OnEmojiClick(btnEmoji);
btnCount++;
}
protected virtual void OnEmojiClick(Button emoji)
{
//Here null check to handle if no subscribers for the event
if(EmojiClicked!=null)
{
//there is no name property define for emoji but only text hence passing only text.
EmojiClicked(this ,new EmojiClickEventArgs(emoji.Text,emoji.Text){ });
}
}
private void Emoji_Clicked(Object sender, EmojiClickEventArgs args)
{
Button mybutton = sender as Button;
Console.WriteLine("emoji text "+ args.Text);
}
}
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...
}
}
I am creating a 2d array of buttons using code and I want to add a button_click() method.
Besides the 2 usual arguments (object sender, EventArgs e) I want to get as an input 2 more variables, To identify which button was clicked, and do something else as a result.
I am currently doing this
arr[i,j].Click+= new EventHandler(button_click);
public void button_click(object sender, EventArgs e)
Is there another way of adding events that will allow me to do what I want?
And on a seperate note. Is there an easy way of creating cubes with a certain color without using buttons?
To identify which button was clicked, and do something else as a result.
You could use sender parameter to identify the button which was clicked.
If you do not want to introduce a custom button type which would have properties for i and j, you could use Tag property to store the indices.
Create a class which inherits from button class. And add 2 properties to it. Then access those properties in your form . Following example is one way to solve your problem.
public class ButtonCtrl : Button
{
public ButtonCtrl(int _arg1, int _arg2)
{
Arg1 = _arg1;
Arg2 = _arg2;
}
public int Arg1 { get; set; }
public int Arg2 { get; set; }
}
//create buttons in form c'tor
public Form1()
{
InitializeComponent();
ButtonCtrl button1 = new ButtonCtrl(1,2);
button1.Text = "dynamic 1";
button1.Click += new EventHandler(button_click);
button1.Top = 10;
this.Controls.Add(button1);
ButtonCtrl button2 = new ButtonCtrl(3, 4);
button2.Text = "dynamic 2";
button2.Click += new EventHandler(button_click);
button2.Top = 30;
this.Controls.Add(button2);
}
And the event handler
public void button_click(object sender,EventArgs e)
{
if(sender is ButtonCtrl)
{
ButtonCtrl btnCtrl= sender as ButtonCtrl;
label1.Text = btnCtrl.Arg1.ToString() + " " + btnCtrl.Arg2.ToString();
}
}