When must we use this operator by events? What is its usage?
Just as += subscribes you a handler to the event, -= unsubscribes it.
Use it when you no longer want a particular handler to be called when the event is raised. You often only need to use it the component raising the event is logically longer lived than the handler of the event - if you don't unsubscribe, the "event raiser" effectively has a reference to the handler, so can keep it alive longer than you want.
As noted in comments:
-= will only remove a single handler; if there are multiple handlers subscribed (even using the exact same delegate) it will still only reduce the handler count by 1. The last instance of the specified handler is the one removed. (So if you previously had handlers A, B, A, C subscribed in that order, and removed A, you'd end up with A, B, C.)
-= doesn't cause an error if the specified handler is not subscribed to the delegate already; it just ignores the request. This is true even if the event has no handlers subscribed to it at the moment.
Just as you can add event handlers via +=, you can remove them via -=.
For instance:
mybutton.Click += new EventHandler(myhandler);
You can later remove it like this:
mybutton.Click -= new EventHandler(myhandler);
...because event handlers for the same method and instance are equivalent (so you don't need to retain a reference to the handler you used with += and use that one with -=).
The += and -= operators can be used in C# to add/remove event handlers to/from one of an object's events:
// adds myMethod as an event handler to the myButton.Click event
myButton.Click += myMethod;
After the above code runs, the myMethod method will be called every time myButton is clicked.
// removes the handler
myButton.Click -= myMethod;
After the above code runs, clicking on myButton will no longer cause myMethod to be called.
You remove the Eventhandler Function.
C# Tutorial, Events and Delegates
I suspect that the background logic of the += is to add the handler to a list/array of event handlers for the given event. When -= is used, it compares your right hand argument to the list of event handlers it is holding for this event and deletes it from the list. If you do multiple += for a given event, each handler will get called.
Stated differently:
+= means add a method to the list of methods to call when the event occurs.
-= means remove the specified method from the list of methods to call.
If all are removed, the event will have no handlers and the event will be ignored.
Related
I dynamically add and remove TextChanged event:
TextBox.TextChanged -= new System.EventHandler(this.textBox_TextChanged);
........
TextBox.TextChanged += new System.EventHandler(this.textBox_TextChanged);
How can I know at some moment if this event was attached or detached?
There is no way to determine if an event was ever attached or removed, particularly not from an event in a class you didn't define. An event defined in another class can only appear on the left side of an add/remove operation - attempting to do otherwise will result in the compiler telling you as much as an error.
If you want to know about this for some reason that can't be better suited otherwise, consider instead raising a flag when attaching this even handler, so that you can query said flag later.
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).
I am developing an application where I assign the events for the button dynamically. Now the thing is that I wish to get all the events for the button click event as I wish to remove the previous handlers.
I tried setting the event handler to null like:
Button.Click += null;
However I received a runtime exception that null cannot be assigned.
I wish to know the events which are already attached to it so that I can remove those events.
Can anybody help me in achieving this?
You cannot assign events - only attach (+=) and remove (-=) operations are available for clients.
Since += and -= are the only operations that are permitted on an event outside the type that declares the event, external code can add and remove handlers for an event, but cannot in any other way obtain or modify the underlying list of event handlers.
A nice pattern is to have an Action removeAll declared somewhere, so you can do:
button.Click += handler
removeAll += () => button.Click -= handler
That way you've only got one variable to keep track of, and you can clear everything just by calling removeAll(), rather than keeping track of all your handlers individually and having to call -= on each of them. It's especially convenient if you've got multiple subclasses of EventHandler to deal with, since otherwise you'd have to keep track of them with multiple lists.
You can't do that (fortunately. Just imagine, that some external code removes your event handler, and your code just stops working in silent manner).
(Reflection isn't an option here, because event implementation may be differ from type to type). Usually, if you want to remove all event handlers this way, this means design error.
My question is related to events:
I have Class with a TaskAComplete Event that is raised when TaskA is complete.
When a button is pressed I subscribe the TaskACompleteEvent
MyObject.TaskAComplete += new EventHandler(MethodToCall);
But in other Event I want to Unsubscribe from the TaskAComplete Event when the Event occurs the first time.
with:
MyObject.TaskAComplete -= MethodToCall;
And then when the Button is pressed the next time to Subscribe the TaskAComplete Event again.
Now when i start the Application and click on the Button the first time it raises the Event correctly.But when i click on the Button the second time the Event is raises two times in a row. (Third time click ->Event is raised three times in a row and so on..)
When i Subscribe the Event in the Contructor of the Form it only raises one time at every click.
Why the Event comes several times?
When you subscribe to an event, you are subscribing by providing a delegate to a method. A delegate is effectively a strongly-typed, object-oriented approach to a C/C++ function pointer.
This delegate then goes into the list of calls for the event.
When you do new EventHandler(MethodToCall) you are explicitly creating that delegate. However, when you do -= MethodToCall, you are removing an "automatic" delegate. It is as if you wrote -= new EventHandler(MethodToCall). Obviously, this new delegate is not the one in the invocation list.
To do what you want, on add, you need to save the new delegate in a variable, which you can later remove. For example:
var handler = new EventHandler(MethodToCall);
MyObject.TaskAComplete += handler;
// later on
MyObject.TaskAComplete -= handler;
You only need to subscribe to the event once. If you subscribe multiple times with the same handler, that handler will be invoked multiple times just like you are seeing.
Why do you want to unsubscribe from the TaskAComplete event in the first place? If your other code is correct, you will get it exactly once for each task.
Suppose I have a form opened via the .ShowDialog() method.
At some point I attach some event handlers to some controls on the form.
e.g.
// Attach radio button event handlers.
this.rbLevel1.Click += new EventHandler(this.RadioButton_CheckedChanged);
this.rbLevel2.Click += new EventHandler(this.RadioButton_CheckedChanged);
this.rbLevel3.Click += new EventHandler(this.RadioButton_CheckedChanged);
When the form closes, I need to remove these handlers, right?
At present, I am doing this when the FormClosing event is fired.
e.g.
private void Foo_FormClosing(object sender, FormClosingEventArgs e)
{
// Detach radio button event handlers.
this.rbLevel1.Click -= new EventHandler(this.RadioButton_CheckedChanged);
this.rbLevel2.Click -= new EventHandler(this.RadioButton_CheckedChanged);
this.rbLevel3.Click -= new EventHandler(this.RadioButton_CheckedChanged);
}
However, I have seen some examples where handlers are removed in the Dispose() method.
Is there a 'best-practice' way of doing this?
(Using C#, Winforms, .NET 2.0)
Thanks.
You don't need to remove the handlers in this case because neither the form nor its buttons are referenced by code external to the form, and the entire object graph will therefore be garbage collected.
No, you don't need to remove the event handlers from controls on the form that is closing. They will all be disposed together.
You're probably thinking of web pages where removing event handlers is needed to avoid memory leaks in the browser.