Usuário com melhor resposta
How to remove all handlers of a click event? (I don't know the names of the methods nor the handlers)

Pergunta
-
How to remove all handlers of a click event?
Note: I don´t know the names of the methods nor the handlers.Ex;
//elemento is Button
EventInfo evInfo = elemento.GetType().GetEvent("Click");
evInfo.RemoveEventHandler(elemento, XXX);Where XXX = Delegate handler
But, I don´t know who is "Delegate handler"......Thanks
- Editado Felipe_Pascoal_SP-BRA quarta-feira, 15 de junho de 2011 20:49 ..
Respostas
-
Ola Felipe... o metodo ClearClick ou ClearEvent... vc pode implementar usar Extension Methods...
o GetInvocationList existem em todos os delegates....
o problema é que vc so pode manipular o evento "Click" dentro da classe e não fora dela...
tipo eu nao posso fazer:
var button = new Button();
Delegate handler = button.Click;
mas dentro da classe Button eu posso fazerDelegate handler = this.Click;... lembrando q um evento é um delegate.... uma vez que vc tenha um objeto do tipo Delegate (ou EventHadler que é filho de Delegate) vc tem o GetInvocationList que te retona todos os metodos atribuidos ao evento ... ai vc pode chamar o RemoveEventHandler....isso serve mesmo se vc usar expressão lambda...button.Click += (sender, args) => { };Ate da para acessar o delegate do metodo em uma classe externa...var eventInfo = teste.GetType().GetEvent("Click");
var methodInfo = eventInfo.EventHandlerType.GetMethod("Invoke");Delegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, methodInfo);mas simplesmente ta dando erro isso ai e não acho o motivo.... ja que no debug os valores do objetos estão corretos....então (apenas) teoricamente ... isso deveria funcionar:
// Seu componenteControl componente = // Seu Control;// Infomarçao do Evento ClickEventInfo eventInfo = teste.GetType().GetEvent("Click");// Invoca o metodo para execução no evento clickMethodInfo methodInfo = eventInfo.EventHandlerType.GetMethod("Invoke");// Intancia em um delegate o metodo de methodInfoDelegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, methodInfo);// Carrega a lista de metodos vinculados no eventovar invocations = handler.GetInvocationList();// Remove todos os metodos do eventoinvocations.ToList().ForEach(item => eventInfo.RemoveEventHandler(this, item));- Sugerido como Resposta AndreAlvesLimaModerator sexta-feira, 17 de junho de 2011 13:49
- Marcado como Resposta AndreAlvesLimaModerator segunda-feira, 4 de julho de 2011 18:25
Todas as Respostas
-
Ola Felipe,
Prmeiramente este é um forum brasileiro, então pedimos para usar o portugues aqui, tudo bem ?
Agora, tente remover os handlers desta maneira:
var eventInfo = this.GetType().GetEvent("Click"); var methodInfo = eventInfo.GetRaiseMethod(); var handler = Delegate.CreateDelegate(typeof(EventHandler), this, methodInfo.Name, false); eventInfo.RemoveEventHandler(this, handler);
-
Olá Rui,
Pode deixar, usarei o português, desculpe.
Então, quando tento recuperar o GetRaiseMethod, ele me retorna null.
var methodInfo = eventInfo.GetRaiseMethod(), a variável "methodInfo" fica null.quando eu tento fazer.
MethodInfo methodInfo = eventInfo.GetAddMethod(), dai ele retorna o "add_click".Porém, não serve para criar o delegate.
Alguma outra idéia ?Obrigado.
-
Realmente... seu problema é mais complicado do que parece... muita coisa que deveria funcionar não rolou...
eu cheguei ate o MethodInfo atribuido ao evento:
var eventInfo = teste.GetType().GetEvent("Click");
var methodInfo = eventInfo.EventHandlerType.GetMethod("Invoke");Mas fica dando erro na criação do Delegate mesmo assim...
var delegateHandler = Delegate.CreateDelegate(eventInfo.EventHandlerType, methodInfo);
var handlers = delegateHandler.GetInvocationList();
foreach (var handler in handlers) {
eventInfo.RemoveEventHandler(teste, handler);
}Vou pensar nisso com mais calma... se eu descobrir algo eu aviso...
-
Não é bem o que vc procura... mas o melhor q eu achei foi isso aqui...
using System; using System.Linq; using System.Windows.Forms; namespace RemoveHandler { class Program { static void Main(string[] args) { var teste = new Teste(); for (int i = 0; i < 10; i++) { teste.Click += teste_Click; } Console.WriteLine("Antes de Remover"); teste.OnClick(); teste.ClearClick(); Console.WriteLine("Depois de Remover"); teste.OnClick(); Console.ReadLine(); } static void teste_Click(object sender, KeyPressEventArgs e) { Console.WriteLine("Clicou"); } static void RemoverHandlers(MulticastDelegate eventDelegate) { } } public class Teste { public event EventHandler<KeyPressEventArgs> Click; public void OnClick() { if (this.Click != null) this.Click(this, new KeyPressEventArgs('a')); } public void ClearClick() { this.ClearEvent(Click, "Click"); } public void ClearEvent<TEventArgs>(EventHandler<TEventArgs> handler, string eventName) where TEventArgs : EventArgs { var invocations = handler.GetInvocationList(); var eventInfo = this.GetType().GetEvent(eventName); invocations.ToList().ForEach(item => eventInfo.RemoveEventHandler(this, item)); } } }
-
Então Rui,
Isso não resolve também...
Não tenho o evento "ClearClick()" nem o evento "GetInvocationList()". Isso porque eu não conheço o "handler".
Eu esqueci de mencionar mas estou trabalhando com WPF e o evento Click está sendo criado no CodeBehind do Xaml.
Eu fiz um esquema utilizando o XamlWrite e XamlRead para ler as informações do "Button" declarado no controle Xaml, porém so vem as informações de propriedades como backugroud, mas os eventos como o "Click", não são retornados.Complicado .........
:??
att.
-
-
Ola Felipe... o metodo ClearClick ou ClearEvent... vc pode implementar usar Extension Methods...
o GetInvocationList existem em todos os delegates....
o problema é que vc so pode manipular o evento "Click" dentro da classe e não fora dela...
tipo eu nao posso fazer:
var button = new Button();
Delegate handler = button.Click;
mas dentro da classe Button eu posso fazerDelegate handler = this.Click;... lembrando q um evento é um delegate.... uma vez que vc tenha um objeto do tipo Delegate (ou EventHadler que é filho de Delegate) vc tem o GetInvocationList que te retona todos os metodos atribuidos ao evento ... ai vc pode chamar o RemoveEventHandler....isso serve mesmo se vc usar expressão lambda...button.Click += (sender, args) => { };Ate da para acessar o delegate do metodo em uma classe externa...var eventInfo = teste.GetType().GetEvent("Click");
var methodInfo = eventInfo.EventHandlerType.GetMethod("Invoke");Delegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, methodInfo);mas simplesmente ta dando erro isso ai e não acho o motivo.... ja que no debug os valores do objetos estão corretos....então (apenas) teoricamente ... isso deveria funcionar:
// Seu componenteControl componente = // Seu Control;// Infomarçao do Evento ClickEventInfo eventInfo = teste.GetType().GetEvent("Click");// Invoca o metodo para execução no evento clickMethodInfo methodInfo = eventInfo.EventHandlerType.GetMethod("Invoke");// Intancia em um delegate o metodo de methodInfoDelegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, methodInfo);// Carrega a lista de metodos vinculados no eventovar invocations = handler.GetInvocationList();// Remove todos os metodos do eventoinvocations.ToList().ForEach(item => eventInfo.RemoveEventHandler(this, item));- Sugerido como Resposta AndreAlvesLimaModerator sexta-feira, 17 de junho de 2011 13:49
- Marcado como Resposta AndreAlvesLimaModerator segunda-feira, 4 de julho de 2011 18:25
-
-