I need to pass a parameter (in C#) to an event handler and then be able to detach the event handler.
I attach the event handler and pass the parameter:
_map.MouseLeftButtonUp += (sender, e) => _map_MouseLeftButtonUp2(sender, e, showResultsWindow);
The event is called as expected. I try to detach the event handler:
_map.MouseLeftButtonUp -= (sender, e) => _map_MouseLeftButtonUp2(sender, e, showResultsWindow);
The code executes without error, but does not seem to detach.
If I attach the event handler the more conventional way (without passing a parameter):
_map.MouseLeftButtonUp+=_map_MouseLeftButtonUp;
and detach
_map.MouseLeftButtonUp -= _map_MouseLeftButtonUp;
everything works as expected
Detaching the event handler (that takes a parameter) via the more conventional way
_map.MouseLeftButtonUp -= _map_MouseLeftButtonUp2;
gives me an error saying the delegates don't match (which makes sense)
So my question is: Why is the event handler not really being detached when I pass a parameter, and is there a way to circumvent this problem.
When you create a lambda (anonymous) function, you're actually creating a new function each time.
The reason your first two lines don't work is because they are two completely different functions that just happen to do the same thing. The correct way to detach would be to have subscribe and unsubscribe from a function, as you've already figured out.
An alternative, that's probably not worth it, is to save your lambda to a variable.
Action<object, MouseButtonEventArgs> myEventMethod = (sender, e) => _map_MouseLeftButtonUp2(sender, e, showResultsWindow);
_map.MouseLeftButtonUp += myEventMethod;
// ...
_map.MouseLeftButtonUp -= myEventMethod;
The reason is that two delegates are not equal:
// You add one delegate instance
_map.MouseLeftButtonUp += (sender, e) => _map_MouseLeftButtonUp2(sender, e, showResultsWindow);
// ..And try to remove another one (not previous!) That's why the first delegate remains unremoved
_map.MouseLeftButtonUp += (sender, e) => _map_MouseLeftButtonUp2(sender, e, showResultsWindow);
You can convince youself by
var x = (sender, e) => _map_MouseLeftButtonUp2(sender, e, showResultsWindow);
var y = (sender, e) => _map_MouseLeftButtonUp2(sender, e, showResultsWindow);
if (Object.Equals(x, y)) { // <- You expected this behaviour
...
}
else { // <- Alas, this is a real situation: x != y
...
}
The reason of such a behaviour is that when Object.Equals is not overridden (and in case of delegates it's not) Object.Equals works as Object.RefrenceEquals does, which checks instances referenses (addresses). Sure, that addresses of x and y are different as well as two your delegates
来源:https://stackoverflow.com/questions/17995339/detach-event-handler-after-attaching-method-with-passed-parameter