1.st part of the quesion:
What is the difference between these 2 event registrations ?
_popUp.AddHandler(PreviewMouseLeftButtonDownEvent, new MouseButtonEventHandler(PopUp_PreviewMouseLeftButtonDown));
_popUp.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(_popUp_PreviewMouseLeftButtonDown);
2.nd part of the question:
or eventually versus
popUp.Opened += PopUp_Opened;
According to Redgate's Reflector, there is no difference. Both methods eventually call the internal method EventHandlerStore.AddRoutedEventHandler. This is the reflector output of the add accessor for the PreviewMouseLeftButtonDown event (in the class UIElement):
public void add_PreviewMouseLeftButtonDown(MouseButtonEventHandler value)
{
this.AddHandler(PreviewMouseLeftButtonDownEvent, value, false);
}
As you can see it calls UIElement.AddHandler for you.
Before you edited your question you were asking about the Opened event of the popup. In that case, there is a difference: First, the Opened event is not implemented as a routed event but as a simple event, so you can't even use the AddHandler call on it. Secondly, the reflector shows that a different method is called in the EventHandlerStore which adds the handler to a simple delegate collection.
The important thing might be the AddHandler(xxx,xxx, false).
If you use true then you can catch events that have already been handled, which can be useful if you subclass Controls like TextBox.
Related
I have a C# class which introduce a new custom event type, and allows users add or remove listeners to it. Also I implement a method which revoves all event listeners during dispatch;
public event EventHandler DataCommited;
private void DetatchListeners()
{
if (DataCommited != null)
{
foreach (EventHandler eh in DataCommited.GetInvocationList())
{
DataCommited -= eh;
}
}
}
It is possible to implement a method which will be taking DataCommited event as an argument. So, I can unsign a set of events using one method. I tried a lot ways implementing it, but unfortunately failed to do it. I wonder if it is actually possible and how. Thank you!!!
It is possible to implement a method which will be taking DataCommited event as an argument.
Well, not really. You can take an EventInfo, but that's all. It's important to understand that this statement:
public event EventHandler DataCommited;
actually creates two things:
An event, which code in other classes can subscribe to and unsubscribe from
A field of type EventHandler, which you can use to call the handlers, or get each one individually.
A simpler implementation of your current code would simply be this:
public event EventHandler DataCommited;
private void DetatchListeners()
{
DataCommitted = null;
}
Unsubscribing from a field-like event just changes the value of the field, after all.
However, if you have an EventInfo, you don't know how that event is implement. It may be backed directly by a field - it might not be... there's no general way of asking an event for its current handlers, or setting a new list of handlers. All you can do directly with an event is subscribe and unsubscribe.
If you only use field-like events, you could use reflection to find the name of the field and set the value to null. You can't do it in general though.
See my article on delegates and events for more information.
I need to test whether my button.Click event is null or not. Here is the event in c#:
button.Click += new Office._CommandBarButtonEvents_ClickEventHandler(Lancement_Formualire_Event);
I tested with
(button.Click == null)
but the compiler refuses to do so.
I tested with (bouton.Click == null) but the compiler refuses to do so.
Indeed. That's not allowed by the abstraction of events. All an event allows you to do is subscribe to it, or unsubscribe from it. You shouldn't care about other subscribers.
You might accomplish what you need if you extend the Button class with an empty "wrapper", which in turn would implement its own Click event and just relay it to Button.Click.
The difference is, that your custom "wrapper" would have at its disposal the very event object, which can be checked like you want to.
It's similar to what is commonly done when implementing INotifyPropertyChanged and should answer your need.
Very basic question, so I'm just looking for a best practice to follow.
My class has a few events which should be subscribed to. (e.g. DiscoveryCompleted). Within the method I do check if the event is null or not, however I'm not sure if I should raise an exception, if so what type. NotImpletementedException?
If the exception is unhandled it doesnt look very elegant.
Your thoughts?
My thought is this is precisely what the NotImplementedException was created for. You should never encounter a NotImplementedException in production code, but it makes it painfully clear during testing that you have a code path that has, well, not been implemented.
Kinda like a TODO comment, but more in-your-face :)
Although, I might question whether having an event handler that must be subscribed to, and not having a default subscriber, doesn't indicate a design issue.
EDIT
I think I misunderstood your initial question slightly, based on your comment. As others have stated (and I questioned), you should not be throwing an exception when you don't have a subscriber to an event handler; simply don't try to call it. If no one cares that event x happened, you can't really do anything about that.
It's not your code's responsibility to care whether anyone cares that it happened, but simply to notify them that it happened if they do care.
EDIT 2 - now with more code
public interface INeedToKnowAboutSomethingImportant
{
void WhenSomethingImportantHappens(SomethingImportantHappenedEventArgs args);
}
public class DoesSomethingImportant
{
private readonly INeedToKnowAboutSomethingImportant _needyDependency;
public DoesSomethingImportant(INeedToKnowAboutSomethingImportant needyDependency)
{
_needyDependency = needyDependency;
}
protected void SomethingImportantHappened(object sender, EventArgs e)
{
//Handle internally
_needyDependency.WhenSomethingImportantHappens(new SomethingImportantHappenedEventArgs(e));
}
}
Following this pattern, you don't have to worry about whether anyone is subscribed to your event handlers. You have to fulfill the dependency, but it doesn't matter AT ALL what you fill it with because whatever it is, it will have that method for you to call.
Events should be optionally subscribed to.
If your class has to call a method, pass a delegate on its constructor instead.
You should not throw NotImplementedException when you check your event. Just check, and execute if not null.
Take for instance. You put an element on your page, but you do not intend to implement any events on the button. The button check for Click event, don't find one, and throws NotImplementedException.
Now that is just wrong.
Event is something that's raised when a certain point the program is hit. Then you can have code that is "triggered" by it. The main path of the code should not be affected whether an event is present or not. If the main path of your code cannot continue without the event being triggered, then you need to use a Method instead.
My suggestion is:
1) Create an event.
2) Subscribe the event with handlers that you are going to implement later.
3) Throw the NotImplementedException in the handler.
As for exception is unhandled, you should never be handling NotImplementedException anyway :P... (And you shouldn't be throwing NotImplementedException for null reference to events).
You should not worry about the event object being null. If no one has subscribed to the event then nothing. If you need another function to run outside of your event raising class, then you need to use another pattern besides the observer pattern. As Eduardo suggested you can pass in a delegate, you might also consider a builder pattern.
I would not throw if an event has no subscribers.
In the "On" method that raises the event you will need a null test (note the race condition prevention). Elsewhere your class should not assume that the event has subscribers.
my previos question is how to clear event handles in c#
Now i need to know that how to check any event handler already assigned?
If the event is in the same class where you will do the check, you can compare to null. But if this is not the case, you should ask yourself why do you care about the inside workings of a class. I mean it is the job of the class which contains the event to care about its subscribers not the opposite. But if you really want this information, the event containing class can expose a property for the outside world - like HasEventHandlers.
Unless I misunderstand the question, a simple check for null should be sufficient. You always need to check for a null in the event handler anyway before calling any event handlers.
In quick watch window I found the btnSubmit click handler with the following expression:
(((System.Web.UI.Control)(btnSubmit)).Events.head.handler).Method
An old solution presented by Jon Skeet where you explicitly implemented event handling would be the best way to address this.
Here is how:
private EventHandler m_myEvent;
public event EventHandler OnEvent
{
add
{
// First try to remove the handler, then re-add it
m_myEvent -= value;
m_myEvent += value;
}
remove
{
m_myEvent -= value;
}
}
In the unlikely scenario that you have multicast delegates, you could experience odd behaviors.
Q1:
“The ListControl.OnSelectedIndexChanged method also allows derived classes to handle the event without attaching a delegate. This is the preferred technique for handling the event in a derived class.”
A) If I understand the above quote, then if we derive a class from ListControl, we should instead of subscribing to SelectedIndexChanged event, treat OnSelectedIndexChanged() method as an event handler and thus put any event processing logic inside it:
protected override void OnSelectedIndexChanged(
EventArgs e
{
//event handling logic
}
Why would that be better than subscribing to an event(inside .aspx) via OnSelectedIndexChanged = ”name_of_event_handler”?
B)
Anyways, in ascx file we use OnSelectedIndexChanged attribute to attach event handler to an event. Name of this attribute is the same as the name of OnSelectedIndexChanged() method. Why is that? Why isn't instead the name of this attribute SelectedIndexChanged:
<asp:ListControl SelectedIndexChanged = ”name_of_event_handler”
Afterall, attribute refers to an event and not to a method ( OnSelectedIndexChanged() ) that calls this event!
thanx
EDIT:
Hello,
HOWEVER, be sure that you call base.On[EventName] or the event won't fire!
Assuming you don’t want anyone else to be able to respond to this event, then would it be perfectly OK not to call base.On[EventName], since I would think not calling it won’t really do any harm besides not firing an event ( and thus event handlers won't be called )?
I realize some events need to be fired in order for Framework to do its job, but what about not calling base.On[SelectedIndexChanged]?
It is "better" in that:
it is cheaper to use virtual (inheritance) where possible - it removes the need for a few extra objects (delegate instances, etc)
it allows the overriding code to know where it comes in the sequence - i.e. if multiple callers are listening, does it fire first? second? in the middle?
The first point is arguably more important for efficiency, especially in things like controls that have sparse event handlers (i.e. things like EventHandlerList instead of a field-like-event).
I don't really understand the second question, but at a guess: convention.
In general, I prefer to override the On[EventName] functions so that I can control if my logic happens before or after the logic in any subscribers.
HOWEVER, be sure that you call base.On[EventName] or the event won't fire!