My understanding about events in C# for a console application:
create a delegate that has the same signature as the event handler method in the subscriber class.
declare an event based on this delegate
raise the event
My understanding of this step is: it is simply an wrapper function where parameters are passed to the event to invoke the event handler functions pointed to by the event.
So raising the event is just invoking the wrapper function in the publish class.
Now when I create a very simple Windows form application, I am not able to apply this general concept.
Consider a WinForms application with just one button.
// registering statement
Button1.Click += new EventHandler (this.button1_click)
I can identify the first step. It is the pre-defined System.EventHandler delegate.
Click event for the button is also pre-defined. No problem with that.
event raising step : here I fail to make the connection between a console application and an Windows application.
Where is the code kept that actually RAISES the event for a WinForms application? We don't seem to have to code it.
I understand click event is raised when someone "clicks" on the button, but how is that realized in the C# code for WinForms application?
How does the compiler "just" knows that a Click event for a button means someone clicking on a button and therefore an event should be raised?
How is click event raised? How are the parameters passed to the event?
The Control class has protected function called WndProc, when the OS needs to tell the program something it generates a Message object and passes it in to the WndProc function.
That WndProc function then looks at the message and sees what kind of message it is, if it is the "mouse left button up" message it runs the the OnClick method with the correct parameters parsed out of the Message object that was passed in to WndProc.
That OnClick method is the thing that raises the event to the subscriber.
From the soruce of .NET:
The entry point of WndProc
It detecting the message type
It parsing and calling the OnClick method
It raising the Click event
Your understanding is a bit backwards. I think this is why you have issues.
You are not creating a delegate that has the same signature as the event handler method in the subscriber class.
What you are doing is declaring what a function to which to delegate execution will look like. Here is the signature for EventHandler:
public delegate void EventHandler(object sender, EventArgs e)
So, if you want a function to be able to handle delegation of the event, it must follow that signature.
Now, the class that will delegate execution to subscribers needs a reference to those functions so it can call them when the event takes place. That is why you implement an event property. It follows then that the Button class must expose this property for you to be able to "hook" your delegates:
public event EventHandler Click
(Notice this is inherited from Control)
When you register an "event handler":
Button1.Click += new EventHandler (this.button1_click)
You are essentially saying that you want this.button1_click(object sender, EventArgs e) to fire whenever the Click event is raised by the Button1 instance.
The Button1 instance will internally decide when to fire the event at which point it will use the event property to delegate execution to the subscribed functions. It will call them with the above mentioned parameters where sender will most likely be the instance itself and the EventArgs class will give you additional information about the conditions that raised the event. The property is also usually implemented to add additional checks (like if there is anything to call in the first place).
As you can see, the code that actually raises the click is internal to the implementation of the Button (or its inheritance chain). It obviously involves mouse tracking and what not, which is the benefit of using the controls by the way, unless you want to write all that detection stuff from scratch.
Related
In my application I have simple EventHandler (in my ViewModel) defined as this :
public event EventHandler FavouriteChangedEvent;
Then when I need, I fire the event with this
FavouriteChangedEvent(this, null);
Everything is working as expected, however in my app, there are clickable links, which opens webbrowser (as separate app). When you go back to the application, then when I try to run FavouriteChangedEvent(this, null); it ends with NullPointerException (From debugging it is beacause FavouriteChangedEvent is really null).
Why is that?
I find this on the internet and used it
public delegate void EventHandler(object sender, string myValue);
public event EventHandler FavouriteChangedEvent = delegate { };
But it does not help much. The application does not fall, but in my View class, I have this line in constructor _dataContext.FavouriteChangedEvent += _dataContext_FavouriteChangedEvent;
After go out and back to the app, this event is not triggered anymore.
Then when I need, I fire the event with this
FavouriteChangedEvent(this, null);
it ends with NullPointerException (From debugging it is beacause FavouriteChangedEvent is really null
This is because there are no event handlers yet.
The event is a class
Once a class has declared an event, it can treat that event just like a field of the indicated delegate type. The field will either be null, if no client has hooked up a delegate to the event, or else it refers to a delegate that should be called when the event is invoked. Thus, invoking an event is generally done by first checking for null and then calling the event.
You have to at least check for null before rising event:
if(FavouriteChangedEvent != null)
FavouriteChangedEvent(this, null);
Note, to make this thread-safe you will have to copy event to local variable, to ensure what null check and rising occurs for the same event:
var event = FavouriteChangedEvent;
if(event != null)
event(this, null);
Described solution (with attaching empty delegate on constructing) is another possible thread-safe solution.
According to event design guidelines:
DO use a protected virtual method to raise each event
This said - do not rise event handler like this, but call protected virtual method (called OnFavouriteChangedEvent) which will rise event. And there is no need to include word "event" into event name. Make it simple: FavouriteChanged.
So I've had an argument with a friend, basically he is saying that this an event handler and I am stating that this is a method. Can you please tell me who's right, and explain what makes this an event handler, if so?
Control ctrlClick;
private void NextColour(object sender)
{
ctrlClick = sender as Control;
// More Code Here
}
Did you subscribe this method to an event like someEvent += NextColour;? Then it's an event handler. Otherwise just a method.
An event handler is a method subscribed to an event, and as it's name implies it gets called back in order to handle the occurrence of the event,once it gets notified by the event publishing mechanism.
If the method has not been subscribed to handle an event, then there is no event for it handle, meaning it's just a method ( maybe a very important one ... :) but still just a method).
im very new to C# as well as lync SDK, can sumone help me to understand the meaning of the below line.
what i understood was whenever lefthand side event occures it will call the rightthand side handler. am i correct?
lyncClient.ConversationManager.ConversationAdded += ConversationManager_ConversationAdded;
You add an event handler called ConversationManager_ConversationAdded to a structure associated with event ConversationAdded. When a ConversationAdded event occurs, all handlers added will be called with arguments defining context of this event occurence.
Quick one:
I've created
public event GridViewEditEventHandler invGridEdit {}.
Can I put code in this event to allow my end user to edit the DB entry, or do I need to point this to a new method for editing?
Edit: It's probably obvious that this is the first time I've looked at events. My apologies if this is a stupid question.
Check the documentation.
In general you have to register your own methods on specific events:
When you create a GridViewEditEventHandler delegate, you identify the
method that will handle the event. To associate the event with your
event handler, add an instance of the delegate to the event. The event
handler is called whenever the event occurs, unless you remove the
delegate. For more information about event-handler delegates, see
Events and Delegates.
In your case:
gridview.RowEditing += new GridViewEditEventHandler(myEditHandler);
Registered methods must have the signature your handler expects. In your case it's the delegate
public delegate void GridViewEditEventHandler(
Object sender,
GridViewEditEventArgs e
)
So the method myEditHandler looks like
void myEditHandler(Object sender, GridViewEditEventArgs e)
To access the firing gridview, perform a cast on sender:
GridView gv = (GridView)sender;
Your method is now called, if the event RowEditing is fired. This is the case, when:
The RowEditing event is raised when an Edit button (a button with its
CommandName property set to "Edit") is clicked, but before the
GridView control enters edit mode. This allows you to provide an
event-handling method that performs a custom routine, such as
canceling the edit operation, whenever this event occurs.
Hope it helps =)
Basically this is for any code you want to run to set up the editing on the grid.
From here:
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridviewediteventhandler(v=vs.110).aspx
The RowEditing event is raised when an Edit button (a button with its CommandName property set to "Edit") is clicked, but before the GridView control enters edit mode. This allows you to provide an event-handling method that performs a custom routine, such as canceling the edit operation, whenever this event occurs.
When you create a GridViewEditEventHandler delegate, you identify the method that will handle the event. To associate the event with your event handler, add an instance of the delegate to the event. The event handler is called whenever the event occurs, unless you remove the delegate. For more information about event-handler delegates, see Events and Delegates.
I've got a component with a custom OnTap handler and I don't want this method to be public.
My problem is that I've got another component layered on the first one, so the latter will intercept every Tap event.
I know that I can just make the first method public and call it from the OnTap event of the second component, but I'm looking for a way to avoid this and just "reroute" the tap event to the other component.
Is this possible?
I can't find anything online!
Just create a public event in your object and have other objects subscribe to it. When OnTap happens raise your own event.
public event EventArgs RouteEvent;
OR
public event Action<EventArgs> RouteEvent;