In C#, how is the best way to add an additional property to a button event call?
Here is the code for the EventHandler:
button.Click += new EventHandler(button_Click);
Here is the code for the button_Click:
private void button_Click(object sender, EventArgs e)
{
}
If I want to add a PropertyGrid parameter to the button_Click function parameters, how is the best way to do this?
I am wanting to do this as the button.Click code is in a function that has a PropertyGrid parameter, and in the button_Click function, I need to set the PropertyGrid selected object. This is only set when the button.Click button is clicked.
If I set the tag of the button to be a PropertyGrid object, how can I retrieve this tag object in the button_Click code?
The button_Click event is called from an object, and the sender is the object, that is not the button.
Can I please have some help with the code?
You cannot convince a Button that it should know anything about a PropertyGrid. When it fires its Click event then it can only tell you about what it knows. Which is cast in stone.
You trivially work around this by using a lambda expression, it can capture the PropertyGrid argument value and pass it on to the method. Roughly:
private void SubscribeClick(PropertyGrid grid) {
button.Click += new EventHandler(
(sender, e) => button_Click(sender, e, grid)
);
}
Related
this is my code and from toolstrip click event i want to call the menustrip sub items
Ex: Menu like : Settings -> User. I want to call user_click event from toolstip click
private void tbrIUC1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
string menuname="mnuuser";
e.ClickedItem.Click += new EventHandler(menuname + "_Click");
}
You can use anonymous delegate:
private void tbrIUC1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
string menuname="mnuuser";
e.ClickedItem.Click += (s, ev) => { your code when clicked };
}
From another stackoverflow post I got the following working for me:
ButtonName.Click += (se, ev) => button1_Click(se, ev);
Link to "inspiration" How can I create a dynamic button click event on a dynamic button?
Look for the answer from A9S6 and the comment to this from Scott Beeson
EDIT
To call a function BASED on the function name (string) I got the following article:
http://www.vcskicks.com/call-function.php
I haven't got it working for me by now but I wanted to share a possible solution
If all fails: I recommend declaring a new method with a Switch that gets the control and the string passed
I am assigning a click event handler like so
var buttonEvent = button.GetType().GetEvent("Click");
var eventMethod = GetType().GetMethod("button_Click");
var handler = Delegate.CreateDelegate(buttonEvent.EventHandlerType, this, eventMethod);
buttonEvent.AddEventHandler(button, handler);
The click event handler is like so:
void button_Click(object sender, EventArgs e) { }
How can I pass custom args into the handler? Ideally I would love
void button_Click(object sender, MyCustomEventArgs e) { }
where I can set MyCustomEventArgs when I assign the event.
Plain and simple, you can't.
The Button class invokes that event, and when it invokes it, it populates the arguments. In this case, with an EventArgs object (no custom data allowed).
This holds true for any event. Unless the class raising the event supports some way of inserting custom data into the event stream, you can't control what it gives you via the event handler.
Note that there is one clever trick for UI event handlers. Because the sending object is held in "sender" and you can put anything in the "Tag" property, you can have custom data in your event by doing:
control.Tag = someObject;
control.Click += (o, e) =>
{
Control c = o as Control;
MyObject data = c.Tag as MyObject;
//use data
};
Also, in WPF, you can do this with CommandParameter since that is also a generic object. Of course, thats not event handlers, but its still the same general idea.
This can seems like a simple question ... the crux is how to match the button delegate signature void, object, eventargs with my method or use an event delegate.
As an example, I have code for a button that changes color when it's clicked. However,
button1.Click += new EventHandler(KK.ChangeColor);
carries the EventArgs from the button to the ChangeColor(object sender, EventArgs e) method, but is meaningless to the rest of the code which use ColorEventArgs; and
button1.Click += delegate(object sender, EventArgs e){ KK.ChangeColor(sender); };
doesn't allow for later removal of the delegate later in the code.
So which is better? Adding unnecessary parameters to all my methods to match the button delegate or suffering from not being able to remove the delegate later ?
or How would I change the delegate signature of the button? It seems there must be a 'cleaner' way to do this?
Will appreciate advice.
"It seems there must be a 'cleaner' way to do this?"
In my opinion, better design would depends on what exactly ChangeColor method do. If it is doing only specific operation that closely related to event button clicked, I would just leave it as the real event handler method. That means, it should have required parameters to match Button.Click event handler signature (I don't think there is option to "change the delegate signature") :
void ChangeColor(object sender, EventArgs e)
{
MessageBox.Show("Button {0} clicked!!!", ((Button)sender).Name);
}
Otherwise, if it is doing not only specific operation related to event button clicked, I would refactor codes unrelated to button click event to another method. This way, the other method doesn't need to have unnecessary parameters. For example :
void ChangeColor(object sender, EventArgs e)
{
var buttonName = ((Button)sender).Name;
MessageBox.Show("Button {0} clicked!!! Save form data", );
//assume that form name can be determined from name of button being clicked
SaveFormToDatabase(buttonName);
}
private void SaveFormToDatabase(string formName)
{
//save form specified in parameter
}
If I have a button which does something and also a double-click event on a data grid which I want to do the same thing, what is the best way to ensure that only one function has to be maintained?
Apart from doing the following, is there any fancy C# way to indicate that two events are to do the same thing?
void button1_Click(...) { MyFunction(); }
void dataGrid1_DoubleClick(...) { MyFunction(); }
void MyFunction() { // do stuff }
I suppose that you are talking about a DataGridView (WinForms) so the signature of the event DoubleClick in the DataGridView and the signature of Click event on a button control is the same.
(An EventHadler). In this case you can simply set the same method using the form designer or manually bind the event
dataGridView1.DoubleClick += new EventHandler(MyFunction);
button1.Click += new EventHandler(MyFunction);
Of course the MyFunction method should match the expected signature of an EventHandler
private void MyFunction(object sender, EventArgs e)
{
// do your work
}
Reviewing my answer after a few minutes I wish to add:
If you find yourself in a situation in which you need to differentiate between the controls using the sender object (like Control c = sender as Control; if (c.Name == "someName") ) I really suggest you to return to the first idea. Call a common method but keep the EventHandler separated for each control involved.
Using VS, in the form's designer view You can set the procedure You want to call to each control's each event in the control's properties window.
image
Just to add to what Steve said, you will want to bind these events to your function manually in the Load event of your form, instead of using the events under the lightning bolt in the properties window in the designer, like so:
private void Form1_Load(object sender, EventArgs e)
{
button1.Click += MyMethod;
dataGridView1.DoubleClick += MyMethod;
}
void MyMethod(object sender, EventArgs e)
{
//Do Stuff
}
Also, declaring a new instance of the EventHandler class has been redundant since Anonymous methods were introduced to C#, you can just point the event directly at the method as shown above.
I have DataList which contains different fields. One of them is next DataList. This inner DataList contains button. And now I would like to bind data for the inner DataList in code behind in OnItemDataBound method. And I need to write there delegate for button. How can I do it? I find the button as the follow:
((Button)e.Item.FindControl("btn_down"))
And now I would like somehow to define what it should do
And it's important I don't want to use:
((Button)e.Item.FindControl("btn_down")).Click +=new EventHandler(btn_Click);
as I need to use some data from OnItemDataBound in this 'Click' function
((Button)e.Item.FindControl("btn_down")).Click +=new EventHandler(btn_Click);
private void btn_Click(object sender, EventArgs e)
{
}
Edit, if you need a custom event handler instead of the default one:
((Button)e.Item.FindControl("btn_down")).Click += new EventHandler(delegate(Customer Parameters Here) {});
private void btn_Click(Customer Parameters Here)
{
}
Ok,
I found a solution:
((Button)e.Item.FindControl("btn_up")).Click += new EventHandler(delegate(object s, EventArgs args) {});