Domanda

Come posso lanciare un evento con accessi come questo:

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

Se fosse un evento normale lo lancerei da:

CanExecuteChanged(sender, EventArgs..). 

Ma qui non funziona - posso solo farlo

CanExecuteChanged +=..

per allegare un metodo esegui l'evento, ma non riesco ad avviarlo.

Anche una certa documentazione sull'argomento sarebbe apprezzata. Grazie.

Modifica L'evento proviene dalla classe che implementa ICommand in WPF. non c'è altro da mostrare :). E no: CommandManager.RequerySuggested (questo, EventArgs.Empty); non funziona.

EDIT2 Non sono sicuro di cosa dire - l'esempio di Jon avrebbe dovuto funzionare ancora anche se il metodo add fosse chiamato correttamente - quando provo a chiamare l'evento - è null: |. Probabilmente lo farò rilasciare eventi con gli accessori.

È stato utile?

Soluzione

Quell'evento si sta semplicemente iscrivendo e cancellando da un altro evento. Se vuoi che i tuoi abbonati (e solo i tuoi abbonati - non quelli separati dall'altro evento) vengano invocati, dovrai tenerli separati separatamente. Ad esempio, potresti cambiare il codice in qualcosa del tipo:

private EventHandler canExecuteChanged;

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

Altri suggerimenti

Penso che tu abbia degli eventi confusi con i delegati. Solo la classe che espone l'evento può sollevarlo ... Altri possono solo iscriversi e cancellarsi. Se stai invocando l'evento all'interno della classe che dichiara l'evento, dovrebbe funzionare come un normale delegato.

La migliore pagina che ho trovato su Events vs Delegates . Leggi ..

Puoi pubblicare uno snippet più grande .. qualcosa sembra storto ..

Aggiornamento Killer

Penso di aver finalmente visto il tuo problema e come risolverlo. Risposta breve: Non si conosce il nome del delegato da invocare se si scrivono i propri accessori. In caso contrario ... il compilatore aggiunge il delegato privato di nome noto e quindi è in grado di invocarlo

Questo frammento di codice mostra cosa intendo. Questo questo articolo di MSDN mi ha mostrato la luce . Grande domanda amico .. Ho perso 30 minuti. Aggiornato :)

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!");
        }
}

Ok, ho scoperto che se voglio innescare quell'evento devi fare:

CommandManager.InvalidateRequerySuggested();.

Devi invocare direttamente gli eventi sottostanti. Nel tuo caso, sembra che questo sarebbe:

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

/ EDIT: Ok, non ho notato che CommandManager è una classe di framework. In questo caso, ovviamente, non vuoi fare ciò che ho proposto. La soluzione di Jon è al punto: devi tenere traccia del tuo evento e invocarlo (ad es. Come delegato). In linea con l'esempio di Jon, l'invocazione sarebbe simile a questa:

canExecuteChanged(sender, EventArgs.Empty);

wow, ho avuto problemi simili. La risposta che mi ha aiutato a capire è un po 'come di Gishu .

Anche dalle specifiche C #, http: // www. microsoft.com/en-us/download/details.aspx?id=7029 , in " 10.8.1 Eventi simili a campi " dice " Durante la compilazione di un evento simile a un campo, il compilatore crea automaticamente spazio di archiviazione per contenere il delegato, "

specifiche dice anche:

  

Pertanto, una dichiarazione di evento di istanza del modulo:

class X
{
   public event D Ev;
}
  

potrebbe essere compilato con qualcosa di 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; }
      }
   }
}

Se fai qualcosa come il codice qui sotto, il compilatore lo compila correttamente:

namespace ConsoleApplication1
{    
    class Program 
    {
        public event EventHandler ss;

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

            }
        }

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

E se aggiungi accessori alla pagina precedente, NON verrà compilato:

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();
        }
    }
}

Ci sono due tipi di eventi dimostrati qui

  1. Eventi simili a campi = > possiamo invocare
  2. eventi con accessori = > non possiamo invocare (non lo trovo nelle specifiche perché, forse l'ho perso) (e lo stavo provando solo su Visual Studio 2005, e le specifiche erano le ultime, immagino)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top