Click here to Skip to main content
15,901,426 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
hi everyone
i spent this three days trying to really understand events and how they work,now i know are they benefits and how to use them but what i can't understand is the technic when a class derive from eventargs,as i can see in the aricles i could find that trying to explain this,we can always work and have the same result without deriving from this class.MSDN wasn't helpful.

can you please uncover the truth behind this Eventargs or suggests articles to mention the benefit of this class?

thanks any way
Posted
Comments
Sergey Alexandrovich Kryukov 6-Apr-13 20:03pm    
This topic is too simple for a whole article; I basically explained it all. However, there are more delicate secrets about delegates and events which are not well described in MSDN. However, if you just need to use available and create custom events correctly, MSDN provides comprehensive description.

If you want to know some internals, I can recommend a section from my article, "On the Nature of Delegate Instance":
http://www.codeproject.com/Articles/203453/Dynamic-Method-Dispatcher#a4.1

This is not all, but it can give your the idea on what's involved. Your follow-up questions are welcome.
—SA

1 solution

MSDN is perfectly helpful in case of .NET, for those who can add and understand documentation.

Your considerations about the case when you "have the same result" is the bright case of false proof. Who told you that you should always derive from System.EventArgs class? For many events, it is really not needed. Those are the events when no information need to be passed from the code where the event is invoked (which is possible only in the class declaring the event), to the event handler.

The example of the events when no information is passed throw EventArgs (as you can see, I don't count the first parameter of the event handler, Object sender which is always passed and rarely used), is the event like Button.Click. For the event handler, nothing is important except the fact that some button is just clicked. For the logic on the button functionality, it is not important, how it was "clicked", by a real click of a mouse of by blank space key, or, maybe, by selecting the button and then hitting Enter; if a mouse was used, the position of mouse pointer inside the button's client are is not important. Such approach is very good, because it helps to unify all kinds of "click" to handle then in the same way.

To find an example of the cases when deriving of the EventArgs class is really important, it's enough to take a look at on of the many available events. Let's, for example, look at the event System.Windows.Control.MouseDown:
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.mousedown.aspx[^].

As you can see, the signature of the handler is defined by the type MouseHandler, which can be defined as System.EventArgs<System.Windows.Forms.MouseEventArgs>:
http://msdn.microsoft.com/en-us/library/system.windows.forms.mouseeventargs.aspx[^].

As you can see, this type inherited from System.EventArgs provides additional properties to pass information on the mouse button which was clicked, mouse pointer location, and so on. In turn, this type is used as a base type to other event arguments types used for more specialized events, such as the ones for a tree node, etc.; naturally, some control-specific information is also passed.

According to the event declaration, the signature of the event handler includes the second parameter of the type System.Windows.Forms.MouseEventArgs:

C#
myControl.MouseDown += delegate(object sender, System.Windows.Forms.MouseEventArgs eventArgs) {
   // use eventArgs.Button, if required
   // use eventArgs.Location, if required
   // and so on...
};


I intentionally did not use lambda form of the event handler in the above code sample, to demonstrate the signature of the handler explicitly. With lambda, type inference can be used (with C# v.3 and above):

C#
myControl.MouseDown += (sender, eventArgs) => {
   // use eventArgs.Button, if required
   // use eventArgs.Location, if required
   // and so on...
};


When you need to create a custom event in your own class, you can use one of the available event argument classes. However, if you need to handle your event with passing some parameters specific to your class, you would need to declare your own event argument class and add some new properties to it. The base class can be System.EventArgs, but not always, sometime you can use some more derived event argument classes for your base class.

[EDIT]

It's important to understand that the use of the delegate type System.EventArgs or the generic delegate type System.EventArgs<> is just a recommended practice and not formally required by CLR and syntax. However, this is the highly recommended pattern for events (but not for other delegate instances, which can use any delegate types).

Please see my comments below to the answer.

—SA
 
Share this answer
 
v4
Comments
Sergey Alexandrovich Kryukov 6-Apr-13 22:28pm    
[OP commented:]

"Your considerations about the case when you "have the same result" is the bright case of false proof.

yes, beginners mistakes Smile | :) .

Actually i sad that because the examples i read where always possible to do without eventarg.in other word they derive from EventArgs but when they pass it to handlers they don't use the EventArgs e .
one last question : when we don't need to pass informations to handlers .is there any different if we derive from EventArgs or not. or it's just a conventional.

thanks a lot Sergey.the MouseEventArgs example clarify my doubts now.

Best of luck.
Sergey Alexandrovich Kryukov 6-Apr-13 22:48pm    
You are very welcome.

First of all, please don't post such content as the solution. I removed it; "Add you solution here" is only intended for the posts providing some help in response to the questions; so using it would only bring you down-votes or abuse reports which you don't want.

I appreciate your constructive attitude to some criticism; of course, we all do mistakes, not only beginners, and criticism helps us to improve ourselves. For example, if someone points out my mistakes, which really happens from time to time, I use this information to fix them.

I admitted that the behavior of event and delegate instanced are not clearly described; I only said that the role of event argument types and the technique of using them and derived classes is well described. I missed one fact that I need to explain now:
The declaration of event members in the form event System.EventHandler<SomeEventArgsType> is not formally required by syntax; this is simply the way to enforce the signature of the handler in the form System.EventHandler(Object sender, SomeEventArgsType args), where System.EventHandler is used as a delegate type. Formally, you can use a delegate type with any other signature, with no parameters, one or more parameters, etc.). The use of System.EventHandler is only a recommended practice (for events, but not the other delegate instances, which can use any delegate types at all), which is the best to follow (for example, FxCop tool (see) will fail the validation of your code is other signatures of event handlers for events are used).

This should answer your question. You idea was correct: this is only conventional, but highly recommended. You can call it just a pattern. I hope you could see the convenience of this pattern. I think your question reveals that you understand the matter.

It's also important to note that the delegate type has nothing to do with the event or delegate instance (normally, declared type is either the same as runtime type, or a base type for actual runtime type, but not in case of delegate types). Actually, event and delegate instances are some classes which hold the invocation list inside the instance, as well as other important implementation detail. The delegate type is not a type of the delegate instance. The delegate type is something defining signature for the handler methods.

Good luck, call again,
Cheers,
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900