Working with "object sender, EventArgs e" inside an Event Handler - c#

When I manually cast the object sender and Eventargs e to a class like below what is it I am exactly doing? I know that it allows me to access all the arguments that have been passed and also to manipulate the object sender (as below):
private void Button1_Click(object sender, EventArgs e)
{
/ /casting the arguments
MouseEventArgs eventargs = e as MouseEventArgs;
Button button1 = sender as Button;
// displays which mouse button I used
MessageBox.Show(eventargs.Button.ToString());
// displays the name of the button I clicked
MessageBox.Show(button1.Name.ToString());
// changes the text of the button
button1.Text = "Ive changed";
}
I feel like I don't understand how this works, only that it works.
Also, it seems quite easy to write an event handler that serves several objects of the same type, but not one that can handle different types of event or different types of object ie:
private void Generic_Event_Handler(object sender, EventArgs e)
{
// displays what object and event triggered the handler
MessageBox.Show(sender.ToString());
MessageBox.Show(e.ToString());
}
Is this ever used? Is there a decent explanation of eventhandlers out there?

The following signature
private or protected void EventHandlersName (object sender, EventArgs e)
is the signature that they have all the event handlers in .NET. The parameter called sender is associated with the object on which the event called e was raised.
Why the type of sender is object?
Because all types in .NET has as their base type the type System.Object. So this way it doesn't make any difference if we have a click event on button on a win form, or in a WPF applciation or in an ASP.NET web form button.
Why we should manually cast the object sender?
We should do so, in order we have access to the properties and the methods of the specific type we have in each case.
For instance, all controls may not have a property called Name. Furthermore the base type called System.Object doesn't have. So if you don't cast the object sender to a Button class, then you can't read it's property called Name.

The signature of an event handler in .Net is (or at least should be):
(object sender, XXArgs e) where XXArgs is a class that inherits from EventArgs.
sender is, well, the sender of the event. In your example, if you click on a button, the button will fire the event using its own instance reference (this) for the sender parameter (so sender is a reference to your button). This is useful because you don't need to store references to the sender of the event ; it's available right here in the event handler.
For the XXArgs part, it contains information about the event. You shouldn't cast it actually, but write your handler with the right signature.
Basically, for a mouse click on a button, the right signature of the event handler would be:
private void Control_MouseClick(Object sender, MouseEventArgs e)
{
}

sender is a reference to type object. The actual object that it refers to could be anything; (in the specific case of an event handler, if everything is working as intended it should refer to the control that generated the event). When you say:
Button button1 = sender as Button;
you are trying to use a Button reference to refer to the same underlying object. If the underlying object is compatible (ie: is a Button), then the button1 reference will enable you to utilize the Button members of the underlying object. Otherwise, with the sender reference, you would only have been able to utilize the object members of the underlying object.
Note that it could still be something more "concrete" or specific than a Button, and then you would need a different cast to get at the more derived members.

Also you can cast page in case of protected void Page_Load(object sender, EventArgs e)
var senderInfo = (Page)sender;

Related

Get Content or Name from WPF Label when clicking using MouseLeftButtonUp [duplicate]

What do sender and eventArgs mean/refer to? How can I make use of them (for the scenario below)?
Scenario:
I'm trying to build a custom control with a delete function, and I want to be able to delete the control that was clicked on a page that contains many of the same custom control.
The sender is the control that the action is for (say OnClick, it's the button).
The EventArgs are arguments that the implementor of this event may find useful. With OnClick it contains nothing good, but in some events, like say in a GridView 'SelectedIndexChanged', it will contain the new index, or some other useful data.
What Chris is saying is you can do this:
protected void someButton_Click (object sender, EventArgs ea)
{
Button someButton = sender as Button;
if(someButton != null)
{
someButton.Text = "I was clicked!";
}
}
sender refers to the object that invoked the event that fired the event handler. This is useful if you have many objects using the same event handler.
EventArgs is something of a dummy base class. In and of itself it's more or less useless, but if you derive from it, you can add whatever data you need to pass to your event handlers.
When you implement your own events, use an EventHandler or EventHandler<T> as their type. This guarantees that you'll have exactly these two parameters for all your events (which is a good thing).
Manually cast the sender to the type of your custom control, and then use it to delete or disable etc. Eg, something like this:
private void myCustomControl_Click(object sender, EventArgs e)
{
((MyCustomControl)sender).DoWhatever();
}
The 'sender' is just the object that was actioned (eg clicked).
The event args is subclassed for more complex controls, eg a treeview, so that you can know more details about the event, eg exactly where they clicked.
'sender' is called object which has some action perform on some
control
'event' its having some information about control which has
some behavoiur and identity perform
by some user.when action will
generate by occuring for event add
it keep within array is called event
agrs
FYI, sender and e are not specific to ASP.NET or to C#. See Events (C# Programming Guide) and Events in Visual Basic.

C# button click EventArgs e information

When I click on a button in e.g. a WinForms application, what information is passed to the EventArgs e of the event method? I'm just wondering because I'm using the as keyword to "convert" e to a mouse event in order to get the coordinates of the point where the button was clicked.
EDIT:
In the following example I can convert the variable e to an object of the type MouseEventArgs, and I want to know to what other types of event arguments e can be converted.
private void someEvent(object sender, EventArgs e)
{
int xCoord = (e as MouseEventArgs).X;
}
This depends on the event, The underlying windows messages for most winforms events have no such concept, so where ever the EventArgs were created will determine the type and the information it contains. It could be something from the framework or you can just make up your own class derived from EventArgs.
After .Net4.5 it doesn't even have to derive from EventArgs
You should use System.Windows.Forms.Cursor.Position: "A Point that represents the cursor's position in screen coordinates."
There are 2 parameters: a sender, and an EventArgs. The sender is the object that initialized the event. The EventArgs contains additional information about the event.
From MSDN
// This example uses the Parent property and the Find method of Control to set
// properties on the parent control of a Button and its Form. The example assumes
// that a Button control named button1 is located within a GroupBox control. The
// example also assumes that the Click event of the Button control is connected to
// the event handler method defined in the example.
private void button1_Click(object sender, System.EventArgs e)
{
// Get the control the Button control is located in. In this case a GroupBox.
Control control = button1.Parent;
// Set the text and backcolor of the parent control.
control.Text = "My Groupbox";
control.BackColor = Color.Blue;
// Get the form that the Button control is contained within.
Form myForm = button1.FindForm();
// Set the text and color of the form containing the Button.
myForm.Text = "The Form of My Control";
myForm.BackColor = Color.Red;
}
I'm using the as keyword to "convert" e to a mouse event
Don't do it. Why?
Because if someone uses keyboard (TABs + Enter) or Button.PerformClick call to trigger your button, the conversion will fail and your:
MouseEventArgs mouseArgs = e as MouseEventArgs ;
if (mouseArgs.MouseButton == MouseButton.Left) ...
will lead to NullReferenceException.
You can't guarantee that EventArgs e in OnClick event will be MouseEventArgs. It is just the most common scenario, but not the only one possible.
P.S.: As it has been already pointed by #terribleProgrammer you could use Cursor.Position static property to get the current cursor position in more independent and robust way.
But if the cursor information makes sense only if the button has been triggered by mouse, then you will have just to be careful and handle possible conversion failure:
MouseEventArgs mouseArgs = e as MouseEventArgs ;
if (mouseArgs == null)
{
Logger.Log("mouseArgs is null");
return;
}
if (mouseArgs.MouseButton == MouseButton.Left) ...
EDIT:
There are three main ways to raise the event and three corresponding eventArgs classes:
Using mouse - MouseEventArgs
Using keyboard - KeyEventArgs
Using PerformClick method - I am not sure, but it will probably be just plain EventArgs(to verify just raise it in such a way and take a look at e.GetType()).
Whether there are any other scenarios that will raise it, I don't know. MSDN is of no use for such requests.
P.S.1.: And I want to repeat again - do not assume that e parameter will be of some specific type. Windows Forms API even does not guarantee that e will contain some concrete useful EventArgs-derived class.

Can't pass a Button as a parameter

What I'm trying to do here is really simple but it's not working for me. I've looked up many examples of very similar or matching questions on stackoverflow and others and their solutions haven't worked for me.
Basically (in a very simplified form), I have a button with some text in it. I'd like it so when this button is clicked, a message box shows up displaying the text. However, I have 9 of these buttons (think numbers on a calculator), and I'd like to create a single method that handles all of these clicks, and outputs the correct text depending on the button.. which is why I need to pass the button as a parameter.
Here's the code I have for the method that handles it so far:
private void btn_Click(object sender, EventArgs e, Button b)
{
MessageBox.Show(b.Text);
}
The above small code snippet is the same solution that others have used and had working. However, for me this code doesn't compile and shows an error that says No overload for 'btn_Click' matches delegate 'System.EventHandler'.
When I double click on that error, it takes me to the Designer.cs page for the form, and this is the line of code that has the error:
this.btnN7.Click += new System.EventHandler(this.btnN7_Click);
I have no clue what the overload and delegate parts mean, sorry I'm pretty new to this. I was thinking that maybe overload has to do with constructors but even if that's correct, I'm unsure of what the next step would be.
I have System.Windows.Forms; included properly so the issue shouldn't be that the Button object wasn't recognized.
If you could provide any insight as to what I'm missing or doing wrong, that'd be very sweet! Please let me know if you need any additional information to continue.
And lastly, this is unrelated to my issue but it's a small question that's been irking me ever since I started using VS a week ago: Are the control parameters object sender and EventArgs e that are automatically created for controller events even necessary? Most of the examples I've looked up online omit them. I've just kept them in since they were created by default but I don't really know what kind of function they provide, and I've never had to use those parameters in my methods.
Thanks all! =)
You just need to use sender parameter.You can't subscribe an event handler if the method signature doesn't match with the EventHandler delegate.
private void btn_Click(object sender, EventArgs e)
{
var currentButton = sender as Button;
if(currentButton != null) MessageBox.Show(currentButton.Text);
}
sender will be assigned to an object that triggers the event.So for instance when your button2 is clicked, it will be assigned to button2.Ofcourse you need to attach this event handler to button2's Click event.I have also used the as operator to ensure that a button is triggered the event.In the future if you call this method manually like btn_Click(this, EventArgs.Empty) then the explicit cast will throw an InvalidCastException.Using as operator is always better to avoid this.If the type of the sender is different than Button then currentButton will be null.
which is why I need to pass the button as a parameter.
You don't really have to create that extra parameter. What you need is already there.
object sender is a source of the event, so just call
var btn = (Button) sender;
MessageBox.Show(btn.Text);
and you should be fine.
Are the control parameters object sender and EventArgs e that are automatically created for controller events even necessary?
So now you have a part of an answer for this question. The second part (EventArgs) are needed for passing additional information. Read more about event args on MSDN.
You have two options here:
If you want to access to the button that fired the event, you can do it trough sender
private void btn_Click(object sender, EventArgs e)
{
Button b = (Button)sender;
MessageBox.Show(b.Text);
}
Otherwise, access directly through the button name (in case you know it)

Pass name of button to click event

I am generating a number of buttons with similar or identical content and was hoping to use the names they are given to differentiate them. As the program is creating the buttons dynamically I can't create a separate event for them all and instead need to be able to grab the name to be able to know which button triggered the event.
Is there a way to pass through the name of a button to the click event it initiates? the sender object seems to contain the content but not the name.
It is for a event like this:
private void Button_Click(object sender, RoutedEventArgs e)
{
//getname of button
Canvas.Children.Remove(//name of button\\)
}
Far as I know, WPF does not even assign anything to the Name property automatically - that's just for developers to assign so we can reference the control.
However, you should be able to just pass in the sender to the remove method since it accepts a UIElement argument which Button is derived from.
Canvas.Children.Remove((Button)sender);
I'm not familiar with WPF. If this answer appears to be a junk, I'll delete it.
In ASP.Net, we can cast to a button to get the sender's information. Something like this -
private void Button_Click(object sender, RoutedEventArgs e)
{
var button = sender as Button;
button.Name
}
Perhaps getting at the control's name will work for you
private void button1_Click(object sender, RoutedEventArgs e)
{
Control control = (Control)sender;
Canvas.Children.Remove(control.Name);
}

From where System.EventArgs get its values?

If I have this action function for a button:
private: System::Void button1_Click(System.Object sender, System.EventArgs e)
{}
I am wondering about who will assign for e & sender their values?
The code that raises the event must set the sender and event args. For example, if the button in question is a Winforms element, then the values would be set by the System.Windows.Forms code, and you should be able to find the details for it in the MSDN documentation.
Generally, by convention, the sender will be the object instance that has raised the event. The event args will contain any other information that is relevant to the event.

Categories