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.
Related
I am in the phase of testing the project and I am dealing with a problem with attaching an event handler multiple times to the button.
I have a class with the _btnSelecteProj field, which I assign the button reference via the parameter in the InitProjects method.
Public Void InitProjects (Button btnSelectProject)
{
_btnSelecteProj = btnSelectProject;
_btnSelecteProj.MouseClick += BtnSelectProj_MouseClick;
}
This method is in the runtime called several times and therefore the event handler is assigned multiple times, which I need to prevent.
I realize that this a wrong design. However, it is not possible to refactor the whole project, because I am in a testing phase. I struggle with this problem in several places in the code.
I tried to prevent this problem this way:
_btnSelectedProj.MouseClick -= BtnSelectProj_MouseClick;
_btnSelectedProj.MouseClick += BtnSelectProj_MouseClick;
But it doesn't work.
I appreciate any advice.
In your event you can implement the add/remove operations as explicit methods and check you event handler for null in add.
For example you can check if the value of _btnSelecteProj is changed
public void InitProjects(Button btnSelectProject)
{
if (_btnSelecteProj != null)
{
if (_btnSelecteProj.Equals(btnSelectProject))
return;
_btnSelecteProj.MouseClick -= BtnSelecteProj_MouseClick;
}
_btnSelecteProj = btnSelectProject;
_btnSelecteProj.MouseClick += BtnSelecteProj_MouseClick;
}
I had to add method ClearEventHandlers() and remove event handler proper way.
public void ClearEventHandlers()
{
_btnSelecteProj.MouseClick -= BtnSelectProj_MouseClick;
}
This method runs at the end of the object's life-time.
NOTE: I'm not sure whether this question/answer is useful to someone else...
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.
Why would a 'public event EventHandler cccc' be null?
I have a class that's
public class Builder
{
public event EventHandler StartedWorking;
public Builder()
{
// Constructor does some stuff
}
public void Start()
{
StartedWorking(this, eventargobject); //StartedWorking is null --
}
}
This seems straightforward and something I do all the time? Am I missing something obvious or is there something that could cause this?
EDIT:
Does this mean that if I fire an event that is not subscribed to in a client class I have to check that it is not null?
EDIT-2:
I guess I'd never had events that were never not subscribed to and hence never ran into this --
You learn something new every day
Sorry about the seemingly stupid question....
The event handler will be null unless somebody has subscribed to the event. As soon as a delegate is subscribed to the event, it will no longer be null.
This is why it's always suggested to use the following form for raising events:
public void Start()
{
var handler = this.StartedWorking;
if (handler != null)
{
handler(this, eventArgObject);
}
}
This protects you from a null exception if there has been no subscribers.
As others have already said, it's null because there are no subscribers.
To answer your edit: Yes, you should always check an event for null before triggering it. However, if you just do a plain if(StartedWorking != null){...} you risk a race condition, because it's possible for a subscriber to unsubscribe after the null check but before you trigger the event. Because of this, you should always use this pattern when checking events for null:
protected void OnStartedWorking()
{
EventHandler localEvent = StartedWorking
if(localEvent != null)
{
localEvent(this, EventArgs.Empty);
}
}
This prevents the race condition by taking a copy of the event first so the subscribe list is fixed at the point of copying.
There's more infomration about publishing events on MSDN: How to Publish Events that Conform to .NET Framework Guidelines
(This works because in .net the MultiCastDelegate class in imutable, so any attempt to change the subscriber list on the event won't effect the copy you have made)
If you haven't hooked any event subscribers up to your StartedWorking event, then it will be null. That is how .NET events works.
This article, among other things, demonstrates that you should check for null before invoking an event. This other question and answer demonstrates how you can create events in a way that avoids the null check (basically by adding an empty handler always).
Don't you need to assign a function ?
StartedWorking += new EventHandler(afunction);
void afunction(object sender, EventArgs e)
{
DoSomething();
}
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.