I have an eventhandler attached to a button in a modalpopup window. I am trying to pass parameters in the eventhandler but have not had any success. I have tried both lines of code separately and nothing happens when the button is clicked. Is there any other way to pass multiple data from a modalpopup to a method? I've also tried an EventHandler that called a simple method that does not pass any extra parameters and still got nothing.
Thanks
save.Click += (object sndr, EventArgs ee) => saveIssueModal(sndr, ee, cguid, ddlStatus.SelectedValue.ToString());
or
save.Click += delegate(object sender2, EventArgs ee) { saveIssueModal(sender2, ee, cguid, ddlStatus.SelectedValue.ToString()); };
...
Button save = new Button();
save.Text = "Save";
save.Click += new EventHandler(saveIssueModal);
...
issuePnl.Controls.Add(save);
...
IssuesPanel.Controls.Add(issuePnl);
...
issueMPE = new AjaxControlToolkit.ModalPopupExtender();
issueMPE.ID = "issueMPE1";
issueMPE.TargetControlID = newBtn.ID;
issueMPE.PopupControlID = issuePnl.ID;
IssuesPanel.Controls.Add(issueMPE);
Try this:
save.Click += (sender, args) => saveIssueModal(<Custom Arguments>, args);
EDIT:
Try this for assigning a basic event handler:
save.Click += new EventHandler(saveIssueModal);
Related
I have a code like:
button1.Click += (s, e) =>
{
};
Now how is it possible to remove this handler dynamically? something like:
button1.Click = null;
The point with events is that they are subscribe/unsubscribe, it is not the intention that you should unsubscribe other events then your own. Therefore you need to keep track of your event:
var click = (s, e) =>
{
};
button1.Click += click;
You can then unsubscribe it by:
button1.Click -= click;
EDIT
Seems you can use the approach suggested here.
Having that line:
this.button1.Click += this.button2.Click += (s, e) => MessageBox.Show("Test");
why this line doesn't works
Cannot implicitly convert type void to System.EventHandler
We need to spare one more line to do this?
But imagine if we got 20 button for that
this.button1.Click += this.button(n).Click += MessageBox.Show("Test");
I know what you will say:
You can do a for(each) for each buttons and ...
but what if i need to choose which button I want?
So, why the first line of code doesn't works, and do a such thing exist (wrote differently)
Yes, you need to separately add the event handler to each event, and the error message is telling you exactly why. In C#, this.button2.Click += (s, e) => MessageBox.Show("Test"); does not return the lambda value, so there is nothing there to add to the button1.Click event.
It's also just plain bad style. I had to read the first line twice to realize that you where trying to do. You should never sacrifice clarity in favor of succinctness.
If you want to hook up three or more buttons to a single event handler (inline or fixed), you will need to put them on separate lines.
private void Form1_Load(object sender, EventArgs e)
{
this.button1.Click += new System.EventHandler(this.button1_Click);
this.button2.Click += new System.EventHandler(this.button1_Click);
this.button3.Click += new System.EventHandler(this.button1_Click);
// OR
this.button1.Click += (s, a) => ShowMessageBox("Test1");
this.button2.Click += (s, a) => ShowMessageBox("Test2");
this.button3.Click += (s, a) => ShowMessageBox("Test3");
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("Hello Event World");
}
private void ShowMessageBox(string message)
{
MessageBox.Show(message);
}
I have been tinkering with Events to gain a better understanding of their use in very general situations. I'm surprised to find the following, so I'm probably heading in the wrong direction...the essence of what I'm doing is changing a button to a random color when it is clicked:
Windows Form
public Form1()
{
ColorChanges KK = new ColorChanges();
KK.ColorEventHandler += handle_ColorChanges;
button1.Click += delegate { KK.ChangeColor(button1); };
}
Event Class
class ColorChanges
{
*... properties & constructor*
public void ChangeColor(object sender)
{
*... randomly assign color to ColorEventArgs*
}
protected virtual void onColorEvent(object sender, ColorEventArgs e)
{
EventHandler<ColorEventArgs> ceh = ColorEventHandler;
{
if (ceh != null)
{
ceh(sender, e)
}
}
}
public event EventHandler<ColorEventArgs> ColorEventHandler;
}
Custom Event Args
public class ColorEventArgs : EventArgs
{
public Color xColor { get; set; }
}
Event Handler
public void handle_ColorChanges(object sender, ColorEventArgs e)
{
if (sender is Button)
{
var ButtonSender = (Button)sender;
ButtonSender.BackColor = e.xColor;
}
}
So the edited questions are:
Is use of the EventHandler(TEventArgs) Delegate useful? MS documentation indicates that syntax like
button1.Click += new EventHandler<AutoRndColorEventArgs>(handle_ColorChanges);
is correct, but that will not reach my code to randomly select a color and an error
"No overload for 'handle_ColorChanges' matches delegate >'System.EventHandler' "
so something like
button1.Click += new EventHandler<AutoRndColorEventArgs>(KK.ChangeColor(button1));
or
button1.Click += new EventHandler(KK.ChangeColor(button1));
Error says that a method is required and if I use
"No overload for 'handle_ColorChanges' matches delegate
'System.EventHandler'"
Lambda expressions help thanks for the supporting answers
button1.Click += (sender,args) => KK.ChangeColor(s);
But that doesn't allow un-assignment and that will be required later...
An anonymous delegate has the same problem
button1.Click += delegate(object sender, EventArgs e)
{ KK.ChangeColor(sender); };
The crux of the problem is that my color methods or their delegates do not match the button delegate signature (object, event). I don't care about the button args and want to use my own HOW?
Is the use of the delegate correct?
Yep, what you are doing is assigning an anonymous delegate as your event handler. This is perfectly valid, however, the catch here is you can't unassign the event handler because you have no reference to it. You could keep a reference to it and do it that way (if required)
var clickHandler = delegate { ... };
button1.Click += clickHandler;
...
button1.Click -= clickHandler
If you need access to the parameters of the event handler you will need to add those into the signature e.g.
button1.Click += delegate (object sender, EventArgs args) { ... }
The new EventHandler(SomeHandlerMethod) construct is the long way of doing things, it's synonymous to += SomeHandlerMethod. Your code currently doesn't work because you are trying to actually call the handler inside the constructor when the constructor expects a reference to the method
+= new EventHandler<ColorEventArgs>(KK.ChangeColor);
Is there a better structure for this?
Yeah, you can do it using even less code
button1.Click += (s, args) => KK.ChangeColor(button1);
This is incorrect:
button1.Click += new EventHandler<AutoRndColorEventArgs>(KK.ChangeColor(button1));
Instead of KK.ChangeColor(button1), you just need to specify the event handler method name as you did in here:
KK.ColorEventHandler += handle_ColorChanges;
The event handler method signature should match with the EventHandler delegate.If you want to just call a method in event handler, you can use lambda statement like this:
button1.Click += (s,e) => KK.ChangeColor(s);
Or:
button1.Click += delegate(object s, EventArgs e) { KK.ChangeColor(s); };
By doing this you are creating an anonymous method and attach it to your Click event.
Here is my problem: I had dynamically created some buttons in my page (in the Page_PreInit method), all linked to the same event handler. But those buttons don't fire the event when I click on them... Can someone help me?
Here is some of my code:
Button creation (on a foreach loop on the Page_PreInit method):
Button b = new Button();
field.Controls.Add(b);
b.Text = "Download";
b.ID = tmp_out[type] as String;
b.Click += new EventHandler(Download_Click);
The OnClick method:
private void Download_Click(object sender, EventArgs e)
{
//doing some stuff
}
Dynamic controls must be added during Page PreInit or Init, not on load. This is because of page lifecycle and viewstate loading... so try that first to see if that solves the problem.
Also, I believe I read that it's best to order your code this way:
Button b = new Button();
field.Controls.Add(b);
b.Text = "Download";
b.ID = tmp_out[type] as String;
b.Click += new EventHandler(Download_Click);
Adding the control first to the inner collection, then changing it's properties.
your event handler statement is
b.Click += new EventHandler(Download_Click);
but your method is
private void Download_Command(object sender, CommandEventArgs e)
are you sure its the right method to be triggered?
Should not be like this?
...
b.Click += new EventHandler(Download_Command);
...
private void Download_Command(object sender, EventArgs e)
{
//doing some stuff
}
Ok I solved my problem.
The ids of the buttons was containing some '\'. I just removed those '\' and it works just fine.
Thanks all for your reply!
PREFACE
I have a Windows form Button that exposes the event OnClick (object sender, EventArgs e).
In my application I can handle this by using the classic event handling technique of C#:
// Button Creation
Button button = new Button();
button.Click += MyEventHandler;
Then Windows Form ask me for an handler with the following signature:
public void MyEventHandler(object sender, EventArgs e) { }
Suppose that I would like to use lambda expression to do this I can use the syntax:
button.Click += (sender, args) =>
{
// execute the code
};
The drawback of this is that I can't unsubscribe from a Lambda expression.
QUESTION
What I would like to do is to have an utility class that will allow me to handle any Click event plus using an additional Action as a parameter. So I would like to write something like this:
button.Click += MyUtility.Click(()
=> {
// the custom code the Click event will execute
})
Can I do it in somehow?
You can assign the lambda expression to a local variable or field.
For example:
EventHandler handler = (sender, args) =>
{
// execute the code
};
button.Click += handler;
button.Click -= handler;
If you want to unsubscribe inside the handler, you'll need to assign handler to null, then to the lambda, to avoid definite assignment issues.