How to remove a lambda event handler
The C# specification explicitly states (IIRC) that if you have two anonymous functions (anonymous methods or lambda expressions) it may or may not create equal delegates from that code. (Two delegates are equal if they have equal targets and refer to the same methods.)
To be sure, you'd need to remember the delegate instance you used:
EventHandler handler = (s, e) => MessageBox.Show("Woho");
button.Click += handler;
...
button.Click -= handler;
(I can't find the relevant bit of the spec, but I'd be quite surprised to see the C# compiler aggressively try to create equal delegates. It would certainly be unwise to rely on it.)
If you don't want to do that, you'll need to extract a method:
public void ShowWoho(object sender, EventArgs e)
{
MessageBox.Show("Woho");
}
...
button.Click += ShowWoho;
...
button.Click -= ShowWoho;
If you want to create an event handler which removes itself using a lambda expression, it's slightly trickier - you need to refer to the delegate within the lambda expression itself, and you can't do that with a simple "declare a local variable and assign to it using a lambda expression" because then the variable isn't definitely assigned. You typically get around this by assigning a null value to the variable first:
EventHandler handler = null;
handler = (sender, args) =>
{
button.Click -= handler; // Unsubscribe
// Add your one-time-only code here
}
button.Click += handler;
Unfortunately it's not even easy to encapsulate this into a method, because events aren't cleanly represented. The closest you could come would be something like:
button.Click += Delegates.AutoUnsubscribe<EventHandler>((sender, args) =>
{
// One-time code here
}, handler => button.Click -= handler);
Even that would be tricky to implement within Delegates.AutoUnsubscribe
because you'd have to create a new EventHandler
(which would be just a generic type argument). Doable, but messy.
How do I Unregister 'anonymous' event handler
If you need to unregister an event, I recommend avoiding anonymous delegates for the event handler.
This is one case where assigning this to a local method is better - you can unsubscribe from the event cleanly.
Adding and Removing Anonymous Event Handler
There's an MSDN page that talks about this:
How to Subscribe to and Unsubscribe from Events
Note in particular:
If you will not have to unsubscribe to [sic]
an event later, you can use the
addition assignment operator (+=) to
attach an anonymous method to the
event.
And also:
It is important to notice that you
cannot easily unsubscribe from an
event if you used an anonymous
function to subscribe to it. To
unsubscribe in this scenario, it is
necessary to go back to the code where
you subscribe to the event, store the
anonymous method in a delegate
variable, and then add the delegate to
the event . In general, we recommend
that you do not use anonymous
functions to subscribe to events if
you will have to unsubscribe from
the event at some later point in your
code.
Removing an anonymous event listener
There is no way to cleanly remove an event handler unless you stored a reference to the event handler at creation.
I will generally add these to the main object on that page, then you can iterate and cleanly dispose of them when done with that object.
How can an anonymous event handler unregister itself?
Maybe:
RoutedEventHandler handler = null;
Unsubscribe anonymous method in C#
Action myDelegate = delegate(){Console.WriteLine("I did it!");};
MyEvent += myDelegate;
// .... later
MyEvent -= myDelegate;
Just keep a reference to the delegate around.
Removing anonymous event handler
You can refer to your anonymous method from inside itself as long as you assign a delegate to a variable first:
EventHandler<SomeEventArgs> handler = null;
handler = (s, e) =>
{
_client.AddMemberToTeamCompleted -= handler;
callback(e.Result);
};
_client.AddMemberToTeamCompleted += handler;
Note that you need to declare the variable and assign it separately or the compiler will deem it uninitialized when you come to use it inside the method body.
Removing anonymous event handlers with some parameters
it will not work cause drawEvent is local variable and next time I call CoupleOverlay, it will create new one.
Indeed. You'd basically need to keep an instance variable instead of a local variable. The instance variable would effectively be "the currently subscribed event handler". Then in CoupleOverlay
you'd remove that event handler, create a new one (storing it in the variable) and resubscribing with it.
An alternative would be to use a single event handler, but keep the "current" overlay and map visual as instance variables, used by the event handler. The CoupleOverlay
method would then just need to update those variables.
Related Topics
Loading Dlls into a Separate Appdomain
How to Put a Task to Sleep (Or Delay) in C# 4.0
Is There Really Any Way to Uniquely Identify Any Computer at All
C# - Winforms - Global Variables
Compare Two Datatables to Determine Rows in One But Not the Other
An Attribute Argument Must Be a Constant Expression, ...- Create an Attribute of Type Array
Main Method Code Entirely Inside Try/Catch: Is It Bad Practice
Webclient.Downloadstring() Returns String with Peculiar Characters
How to Unregister 'Anonymous' Event Handler
Multiple String Comparison with C#
C# Rsa Public Key Output Not Correct
How to Implement Url Rewriting Similar to So
Linq - Left Join on Multiple (Or) Conditions
Why Aren't C# Static Class Extension Methods Supported
Best Way to Determine If Two Path Reference to Same File in C#