How to remove all event handlers from an event
I found a solution on the MSDN forums. The sample code below will remove all Click
events from button1
.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
button1.Click += button1_Click;
button1.Click += button1_Click2;
button2.Click += button2_Click;
}
private void button1_Click(object sender, EventArgs e) => MessageBox.Show("Hello");
private void button1_Click2(object sender, EventArgs e) => MessageBox.Show("World");
private void button2_Click(object sender, EventArgs e) => RemoveClickEvent(button1);
private void RemoveClickEvent(Button b)
{
FieldInfo f1 = typeof(Control).GetField("EventClick",
BindingFlags.Static | BindingFlags.NonPublic);
object obj = f1.GetValue(b);
PropertyInfo pi = b.GetType().GetProperty("Events",
BindingFlags.NonPublic | BindingFlags.Instance);
EventHandlerList list = (EventHandlerList)pi.GetValue(b, null);
list.RemoveHandler(obj, list[obj]);
}
}
How to remove all eventhandler
Simply set the event to null
:
this.Something = null;
It will unregister all event handlers.
Is it possible to remove all event handlers of a given element in javascript?
http://www.quirksmode.org/js/events_advanced.html - "Which event handlers are registered?" - it seems it's not possible without DOM 3 level :-(
EDIT: I've come up with this code. It suits my needs. Maybe it will be helpful for someone else.
Javascript:
function DomLib() {
}
/**
* Based on: http://ejohn.org/blog/flexible-javascript-events/
* Function that register event and enables it to be removed without explicitly giving the function definition
*/
DomLib.prototype.regEventEx = function (el, eventName, funct) {
if (el.attachEvent) {
el['e'+eventName+funct] = funct;
el[eventName+funct] = function(){el['e'+eventName+funct](window.event);}
el.attachEvent( 'on'+eventName, el[eventName+funct] );
} else {
el.addEventListener(eventName, funct, false);
}
if(!el.eventHolder) el.eventHolder = [];
el.eventHolder[el.eventHolder.length] = new Array(eventName, funct);
}
DomLib.prototype.removeEvent = function (obj, type, fn) {
if (obj.detachEvent) {
obj.detachEvent( 'on'+type, obj[type+fn] );
obj[type+fn] = null;
} else {
obj.removeEventListener( type, fn, false );
}
}
DomLib.prototype.hasEventEx = function (el, eventName, funct) {
if (!el.eventHolder) {
return false;
} else {
for (var i = 0; i < el.eventHolder.length; i++) {
if (el.eventHolder[i][0] == eventType && String(el.eventHolder[i][1]) == String(funct)) {
return true;
}
}
}
return false;
}
/**
* @return - returns true if an event was removed
*/
DomLib.prototype.removeEventsByTypeEx = function (el, eventType) {
if (el.eventHolder) {
var removed = 0;
for (var i = 0; i < el.eventHolder.length; i++) {
if (el.eventHolder[i][0] == eventType) {
this.removeEvent(el, eventType, el.eventHolder[i][1]);
el.eventHolder.splice(i, 1);
removed++;
i--;
}
}
return (removed > 0) ? true : false;
} else {
return false;
}
}
Testing HTML page:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<meta http-equiv="Expires" content="Fri, Jan 01 1900 00:00:00 GMT">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Lang" content="en">
<meta name="author" content="">
<meta http-equiv="Reply-to" content="@.com">
<meta name="generator" content="PhpED 5.8">
<meta name="description" content="">
<meta name="keywords" content="">
<meta name="creation-date" content="01/01/2009">
<meta name="revisit-after" content="15 days">
<title>DomLibTest</title>
<link rel="stylesheet" type="text/css" href="my.css">
<!-- FILL IN: Location of your jQuery library -->
<script type="text/javascript" src="jQuery/jQuery-current.js"></script>
<!-- FILL IN: Plugin for debugging ... http://www.ecitadel.net/blog/2009/12/08/developing-jquery-use-dump-instead-alert -->
<script type="text/javascript" src="jQuery/jQuery.dump.js"></script>
<script type="text/javascript" src="DomLib.js"></script>
</head>
<body>
<div id="testElem-1"></div>
<script type="text/javascript">
<!--
var domLib = new DomLib();
function removeTest(el) {
var funct = function() { alert("#1: How Are You?");};
var funct2 = function() { alert("#2: How Are You?");};
domLib.regEventEx(el, "click", funct);
domLib.regEventEx(el, "mousemove", funct2);
domLib.regEventEx(el, "mousemove", funct2);
domLib.regEventEx(el, "mousemove", funct2);
$.dump(el.eventHolder);
domLib.removeEventsByTypeEx(el, "mousemove");
$.dump(el.eventHolder);
}
removeTest(document.getElementById('testElem-1'));
-->
</script>
</body>
</html>
How to remove all event handlers from an event?
It is the lambda expression that is getting you into trouble here. Don't dig a deeper hole, just use AddressOf and a private method instead so you can trivially use the RemoveHandler statement.
If you absolutely have to then keep in mind that the VB.NET compiler auto-generates a backing store field for the event with the same name as the event with "Event" appended. Which makes this code work:
Dim Obj = New SimpleClass
AddHandler Obj.SimpleEvent, Sub()
MsgBox("Hi !")
End Sub
Dim fi = GetType(SimpleClass).GetField("SimpleEventEvent", BindingFlags.NonPublic Or BindingFlags.Instance)
fi.SetValue(Obj, Nothing)
Obj.SimpleMethod() '' No message box
I'll reiterate that you should not do this.
How would it be possible to remove all event handlers of the 'Click' event of a 'Button'?
You can't, basically - at least not without reflection and a lot of grubbiness.
Events are strictly "subscribe, unsubscribe" - you can't unsubscribe someone else's handler, any more than you can change someone else's reference to an object.
remove all EventHandlers of a specific Control
According to this,
for cancelling all Click Events of panel1 do this:
FieldInfo f1 = typeof(Control).GetField("EventClick", BindingFlags.Static| BindingFlags.NonPublic);
object obj = f1.GetValue(panel1);
PropertyInfo pi = panel1.GetType().GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Instance);
EventHandlerList list = (EventHandlerList)pi.GetValue(panel1, null);
list.RemoveHandler(obj, list[obj]);
And for cancelling other events of panel1 change EventClick
to event name that you want to remove.
One can get all event names using this code:
EventInfo[] info = type.GetEvents();
for (int i = 0; i < info.Length; i++)
{
Console.WriteLine(info[i].Name + "\n");
}
Javascript/DOM: How to remove all event listeners of a DOM object?
I am not sure what you mean with remove all events. Remove all handlers for a specific type of event or all event handlers for one type?
Remove all event handlers
If you want to remove all event handlers (of any type), you could clone the element and replace it with its clone:
var clone = element.cloneNode(true);
Note: This will preserve attributes and children, but it will not preserve any changes to DOM properties.
Remove "anonymous" event handlers of specific type
The other way is to use removeEventListener()
but I guess you already tried this and it didn't work. Here is the catch:
Calling
addEventListener
to an anonymous function creates a new listener each time. CallingremoveEventListener
to an anonymous function has no effect. An anonymous function creates a unique object each time it is called, it is not a reference to an existing object though it may call one. When adding an event listener in this manner be sure it is added only once, it is permanent (cannot be removed) until the object it was added to, is destroyed.
You are essentially passing an anonymous function to addEventListener
as eventReturner
returns a function.
You have two possibilities to solve this:
Don't use a function that returns a function. Use the function directly:
function handler() {
dosomething();
}
div.addEventListener('click',handler,false);Create a wrapper for
addEventListener
that stores a reference to the returned function and create some weirdremoveAllEvents
function:var _eventHandlers = {}; // somewhere global
const addListener = (node, event, handler, capture = false) => {
if (!(event in _eventHandlers)) {
_eventHandlers[event] = []
}
// here we track the events and their nodes (note that we cannot
// use node as Object keys, as they'd get coerced into a string
_eventHandlers[event].push({ node: node, handler: handler, capture: capture })
node.addEventListener(event, handler, capture)
}
const removeAllListeners = (targetNode, event) => {
// remove listeners from the matching nodes
_eventHandlers[event]
.filter(({ node }) => node === targetNode)
.forEach(({ node, handler, capture }) => node.removeEventListener(event, handler, capture))
// update _eventHandlers global
_eventHandlers[event] = _eventHandlers[event].filter(
({ node }) => node !== targetNode,
)
}
And then you could use it with:
addListener(div, 'click', eventReturner(), false)
// and later
removeAllListeners(div, 'click')
DEMO
Note: If your code runs for a long time and you are creating and removing a lot of elements, you would have to make sure to remove the elements contained in _eventHandlers
when you destroy them.
Remove All Event Listeners of Specific Type
That is not possible without intercepting addEventListener
calls and keep track of the listeners or use a library that allows such features unfortunately. It would have been if the listeners collection was accessible but the feature wasn't implemented.
The closest thing you can do is to remove all listeners by cloning the element, which will not clone the listeners collection.
Note: This will also remove listeners on element's children.
var el = document.getElementById('el-id'),
elClone = el.cloneNode(true);
el.parentNode.replaceChild(elClone, el);
Related Topics
Why Did I Get the Compile Error "Use of Unassigned Local Variable"
How to Pass Table Value Parameters to Stored Procedure from .Net Code
How to Find Out Which Process Is Locking a File Using .Net
How to Write Unicode Characters to the Console
Do Httpclient and Httpclienthandler Have to Be Disposed Between Requests
The Located Assembly'S Manifest Definition Does Not Match the Assembly Reference
Dependency Inject (Di) "Friendly" Library
Best Way to Randomize an Array With .Net
Type Checking: Typeof, Gettype, or Is
How to Remove All Event Handlers from an Event
Why Covariance and Contravariance Do Not Support Value Type
How to Get a User'S Client Ip Address in Asp.Net
How to Get the Webbrowser Control to Show Modern Contents
In C#, Why Is String a Reference Type That Behaves Like a Value Type