2008-10-16 9 views
5

¿Cómo puedo poner en marcha un evento que tiene descriptores de acceso de este tipo:lanzar un evento que tiene accessores

public event EventHandler CanExecuteChanged 
    { 
     add 
     { 
     CommandManager.RequerySuggested += value; 
     } 
     remove 
     { 
     CommandManager.RequerySuggested -= value; 
     } 
    } 

Si se tratara de un evento normal me lanzo por:

CanExecuteChanged(sender, EventArgs..). 

Pero aquí no funciona - yo sólo puedo hacer

CanExecuteChanged +=.. 

adjuntar un método de hacer caso - pero no puedo poner en marcha.

También se apreciará algo de documentación sobre el tema. Gracias.

EDIT El evento es de la clase que implementa ICommand en WPF. no hay nada más que mostrar :). Y no - CommandManager.RequerySuggested (this, EventArgs.Empty); no funciona

EDIT2 No estoy seguro de qué decir - El ejemplo de Jon debería haber funcionado incluso si el método de agregar se llama correctamente - cuando intento llamar al evento - es nulo: |. Probablemente voy a soltar eventos con accesodores.

+0

encontró el problema. Si envuelve a un delegado, debe llamar al delegado directamente en lugar del evento como lo hace normalmente. Ver la publicación a continuación. – Gishu

Respuesta

3

Ese evento es simplemente suscribirse y darse de baja de otro evento.Si desea que sus suscriptores (y solo sus suscriptores - no separados para el otro evento) sean invocados, necesitará mantener sus suscriptores por separado. Por ejemplo, podría cambiar el código a algo como:

private EventHandler canExecuteChanged; 

public event EventHandler CanExecuteChanged 
{ 
    add 
    { 
     CommandManager.RequerySuggested += value; 
     canExecuteChanged += value; 
    } 
    remove 
    { 
     CommandManager.RequerySuggested -= value; 
     canExecuteChanged -= value; 
    } 
} 
0

Tienes que invocar los eventos subyacentes directamente. En su caso, parece que esto sería:

<blockquote>CommandManager.RequerySuggested(sender, EventArgs.…)</blockquote> 

/EDIT: Ok, no me di cuenta de que CommandManager es una clase de marco. En este caso, obviamente no quieres hacer lo que he propuesto. La solución de Jon va al grano: debe hacer un seguimiento de su propio evento e invocarlo (por ejemplo, como delegado). De acuerdo con el ejemplo de Jon, la invocación se vería así:

canExecuteChanged(sender, EventArgs.Empty); 
4

yo creo que hay eventos confundidos con los delegados. Solo la clase que expone el evento puede elevarlo ... Otros solo pueden suscribirse: anular su suscripción. Si invoca el evento desde dentro de la clase que declara el evento, debería funcionar como un delegado regular.

La mejor página que pude encontrar en Events vs Delegates. Leer ..

Se puede publicar un fragmento grande .. algo parece estar mal ..

Killer actualización

creo fin ver su problema y cómo solucionarlo. Respuesta corta: No conoce el nombre del delegado para invocar si escribe sus propios descriptores de acceso. Si no ... el compilador agrega el delegado privado del nombre conocido y, por lo tanto, puede invocarlo

Este fragmento de código muestra a qué me refiero. Esto MSDN article showed me the light. Gran pregunta amigo ... Perdí 30 minutos. Upvoted :)

public class Hash1 
    { 

     private EventHandler myHomeMadeDelegate; 
     public event EventHandler FancyEvent 
     { 
      add 
      { 
       //myDelegate += value; 
       myHomeMadeDelegate = (EventHandler)Delegate.Combine(myHomeMadeDelegate, value); 
      } 
      remove 
      { 
       //myDelegate -= value; 
       myHomeMadeDelegate = (EventHandler)Delegate.Remove(myHomeMadeDelegate, value); 
      } 
     } 
     public event EventHandler PlainEvent; 


     public Hash1() 
     { 
      FancyEvent += new EventHandler(On_Hash1_FancyEvent); 
      PlainEvent += new EventHandler(On_Hash1_PlainEvent); 

      // FancyEvent(this, EventArgs.Empty); //won't work:What is the backing delegate called? I don't know 
      myHomeMadeDelegate(this, EventArgs.Empty); // Aha! 
      PlainEvent(this, EventArgs.Empty); 
     } 

     void On_Hash1_PlainEvent(object sender, EventArgs e) 
     { 
      Console.WriteLine("Bang Bang!"); 
     } 

     void On_Hash1_FancyEvent(object sender, EventArgs e) 
     { 
      Console.WriteLine("Bang!"); 
     } 
} 
+0

Maldición ... De hecho, encontré ese artículo pero no tenía suficientes fragmentos de código :) así que me muevo. Además, Jon explicó casi lo mismo solo más corto :). Pero gracias por entrar en más detalles. Recordatorio: P – sirrocco

1

Bueno, he encontrado que si quiero desencadenar ese evento que tiene que hacer:

CommandManager.InvalidateRequerySuggested();. 
0

wow, acaba de tener problemas similares. La respuesta que me ayudó a entender es algo así como Gishu.

también de la C# características, http://www.microsoft.com/en-us/download/details.aspx?id=7029, en "10.8.1 eventos de campo como" se dice "Al compilar un evento de campo como, el compilador crea automáticamente de almacenamiento para guardar el delegado,"

especificaciones también dice:

Por lo tanto, una declaración evento instancia del formulario:

class X 
{ 
    public event D Ev; 
} 

podría compilarse a algo equivalente a:

class X 
{ 
    private D __Ev; // field to hold the delegate 

    public event D Ev { 
     add { 
     lock(this) { __Ev = __Ev + value; } 
     } 

     remove { 
     lock(this) { __Ev = __Ev - value; } 
     } 
    } 
} 

Si haces algo como el código de abajo, el compilador compila con éxito:

namespace ConsoleApplication1 
{  
    class Program 
    { 
     public event EventHandler ss; 

     Program() 
     { 
      if (null != ss) 
      { 
       ss(this, EventArgs.Empty) ; 

      } 
     } 

     static void Main(string[] args) 
     { 
      new Program(); 
     } 
    } 
} 

Y si agrega accesos a ss arriba, NO compilará:

namespace ConsoleApplication1 
{  
    class Program 
    { 
     public event EventHandler ss 
     { 
      add { } 
      remove { } 
     } 

     Program() 
     { 
      if (null != ss) 
      { 
       ss(this, EventArgs.Empty) ; 

      } 
     } 

     static void Main(string[] args) 
     { 
      new Program(); 
     } 
    } 
} 

Hay dos tipos de eventos demostraron aquí

  1. eventos de campo similar a => podemos invocar
  2. eventos con descriptores de acceso => ​​no podemos invocar (no puede encontrar esto en las especificaciones por qué, tal vez Lo extrañé) (y solo estaba probando esto en Visual Studio 2005, y las especificaciones fueron las últimas, creo)
Cuestiones relacionadas