none
¿Cómo puedo averiguar si un método ya está suscripto a un evento? RRS feed

  • 问题

  • Hola hay alguna manera de saber si un método ya está suscripto a un evento para no volver a suscribirlo

    Por ejemplo yo hago lo siguiente:

    control.MouseLeftButtonUp += new System.Windows.Input.MouseButtonEventHandler(control_MouseLeftButtonUp);
    

    y en realidad lo que quiero saber es si puedo preguntar antes si el método control_MouseLeftButtonUp ya está suscripto para no volver a suscribirlo, o si puedo limpiar todos los suscriptores del evento MouseLeftButtonUp.

    Perdonen si la pregunta es muy básica pero no logro hacer lo que quiero.

    Desde ya gracias, Fernando

    2012年5月2日 20:12

答案

  • Hola Fernando,

    Conocer si un evento esta o no esta suscrito, no lo veo facil sin hacer algún que otro truquillo con Reflection y entonces si se podría conocer si este esta suscrito.

    De todas formas te recomiendo esta lectura del foro donde de verdad se dio una buenísima explicación de como funciona un evento.

    http://social.msdn.microsoft.com/Forums/es/vcses/thread/d28cf2c7-b024-4c1a-93aa-8dc5005ff713 y en este post Nico, trato tambien el tema haciendo referencia a Eduard

    http://nicolocodev.wordpress.com/2012/04/18/delegados-action-func-lambda/

    Si de verdad necesitas conocerlo, lo podemos ver con Reflection. Pero coindico con Leandro que si eso es así es porque el código se ejecuta dos o más veces aunque tu pienses lo contrario. Pon un simple break point y lo verás.

    Saludos,


    phurtado
    Mi Blog Blog
    Sigueme en Twitter

    2012年5月2日 22:21
    版主
  • Hola, Si lo necesitas a nivel del METODO y no del delegado... no se si lo que voy a decir se vea muy feo:), pero es la solucion mas simple que se me ocurre a tu problema.

    Create un campo privado Bool que te informe si esta en uso :D así:

        class Program
        {
            public delegate void ImprPalabra(string palabra);
            private static bool _estaEnUso;
            static void Main(string[] args)
            {
                if (!_estaEnUso)
                {
                    ImprPalabra palabra1 = ImprPalabraConsola;
                    palabra1("Primera llamada");
                }
                if (!_estaEnUso)
                {
                    ImprPalabra palabra2 = ImprPalabraConsola;
                    palabra2("Segunda llamada");
                }
                Console.ReadKey();
            }
            static void ImprPalabraConsola(string palabra)
            {
                Console.WriteLine(string.Format("La palabra es: {0}", palabra));
                _estaEnUso = true;
            }
        }
    Saludos.

    Nicolás Herrera
    Bogotá - Colombia
    BLOG - Leader Group BogotaDotNet
    "Daría todo lo que sé, por la mitad de lo que ignoro." Rene Descartes

    2012年5月4日 14:36

全部回复

  • por lo general en esto caso no preguntas si esta o no esta

    simplemente lo remueves y vuelves a asignar

    pones la linea con el -=

    control.MouseLeftButtonUp -= new System.Windows.Input.MouseButtonEventHandler(control_MouseLeftButtonUp);

    control.MouseLeftButtonUp += new System.Windows.Input.MouseButtonEventHandler(control_MouseLeftButtonUp);

    si estaba lo remueve y asigna, sino estaba bueno no removeria nada y asigna


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    2012年5月2日 20:18
  • Leandro, eso fue lo primero que intenté y no me funciona, el método se suscribe siempre que pasa por esas líneas y cuando se produce el evento se ejecuta la cantidad de veces que pasó por ahí :(
    2012年5月2日 21:02
  • mm eso es raro

    estas seguro que no se adjunto con el  += en algun otro lado ?

    o sea esa es la unica linea de codigo donde adjuntas el evento, porque puede que en otro lado tambien este pasando mas de una vez

    revisa en que puntos adjuntas el evento y valida que solo sea en esos puntos

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    2012年5月2日 21:10
  • Hola Fernando,

    Conocer si un evento esta o no esta suscrito, no lo veo facil sin hacer algún que otro truquillo con Reflection y entonces si se podría conocer si este esta suscrito.

    De todas formas te recomiendo esta lectura del foro donde de verdad se dio una buenísima explicación de como funciona un evento.

    http://social.msdn.microsoft.com/Forums/es/vcses/thread/d28cf2c7-b024-4c1a-93aa-8dc5005ff713 y en este post Nico, trato tambien el tema haciendo referencia a Eduard

    http://nicolocodev.wordpress.com/2012/04/18/delegados-action-func-lambda/

    Si de verdad necesitas conocerlo, lo podemos ver con Reflection. Pero coindico con Leandro que si eso es así es porque el código se ejecuta dos o más veces aunque tu pienses lo contrario. Pon un simple break point y lo verás.

    Saludos,


    phurtado
    Mi Blog Blog
    Sigueme en Twitter

    2012年5月2日 22:21
    版主
  • Hola nandosoldini,

    Para solucionar esto hay que desuscribir y volver a suscribir como dice Leandro, pero no debes volver a crear el Handler, sino directamente el método:

    control.MouseLeftButtonUp -= control_MouseLeftButtonUp;
    control.MouseLeftButtonUp += control_MouseLeftButtonUp;
    

    Yo esto lo he realizado multitud de veces y sí me ha funcioado.

    Salu2 y espero haberte ayudado


    Xavi Paper

    2012年5月2日 23:21
  • Muy buenos links!!!

    Xavi Paper

    2012年5月2日 23:40
  • Gracias a todos, esta tarde pruebo lo que me dicen y les cuento como me fue
    2012年5月3日 15:50
  • Hola, Si lo necesitas a nivel del METODO y no del delegado... no se si lo que voy a decir se vea muy feo:), pero es la solucion mas simple que se me ocurre a tu problema.

    Create un campo privado Bool que te informe si esta en uso :D así:

        class Program
        {
            public delegate void ImprPalabra(string palabra);
            private static bool _estaEnUso;
            static void Main(string[] args)
            {
                if (!_estaEnUso)
                {
                    ImprPalabra palabra1 = ImprPalabraConsola;
                    palabra1("Primera llamada");
                }
                if (!_estaEnUso)
                {
                    ImprPalabra palabra2 = ImprPalabraConsola;
                    palabra2("Segunda llamada");
                }
                Console.ReadKey();
            }
            static void ImprPalabraConsola(string palabra)
            {
                Console.WriteLine(string.Format("La palabra es: {0}", palabra));
                _estaEnUso = true;
            }
        }
    Saludos.

    Nicolás Herrera
    Bogotá - Colombia
    BLOG - Leader Group BogotaDotNet
    "Daría todo lo que sé, por la mitad de lo que ignoro." Rene Descartes

    2012年5月4日 14:36
  • Hola Nico,

    Eso está bien, pero piensa que el evento del que habla Fernando es un evento de WPF y concretamente del objeto UIElement, con lo cual tu alternativa no le sirve excepto que herede de este y que el evento este definido como virtual para poder reemplazarlo. No se si conoces imagino que si los metodos add y remove de un evento, con eso y la técnica que has comentado se podría hacer, pero en este caso lo veo complicado, excepto que como dije accesas por reflectión a algún campo privado donde controlas eso, es decir todo un cirio:)

    Event Add Remove

    Saludos,


    phurtado
    Mi Blog Blog
    Sigueme en Twitter

    2012年5月4日 15:01
    版主
  • Excelente esto me ha funcionado .... tenia el mismo sintoma cada vez que inicializaba se me asignaba un nuevo evento, me causaba un dolor de cabeza, pero lo resolvi con el ejemplo expuesto.

     public static void InicializarSeleccionTransportista(ButtonEdit be, Expression<Func<TrpTransportista, bool>> condicion)
            {
                be.Tag = condicion;

                be.ButtonClick -= Tranportista_ButtonClick;
                be.ButtonClick += Tranportista_ButtonClick;
                be.CustomDisplayText += Tranportista_CustomDisplayText;
            }

    2022年10月11日 22:48