Pergunta

Como posso lançar um evento que tem acessores como esta:

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

Se fosse um evento normal eu iria lançá-lo por:

CanExecuteChanged(sender, EventArgs..). 

Mas aqui ele não funciona - eu só posso fazer

CanExecuteChanged +=..

para anexar um método fazer o evento - mas não posso iniciá-lo.

Além disso, alguns documentos sobre o assunto seria apreciada. Obrigado.

Editar O evento é de classe que implementa ICommand no WPF. não há nada mais para mostrar :). E não - o CommandManager.RequerySuggested (este, EventArgs.Empty); não funciona.

EDIT2 Não sei o que dizer - o exemplo de Jon deveria ter trabalhado ainda mesmo que o método add é chamado corretamente - quando tento chamar o evento - é nulo: |. Eu provavelmente irá soltar eventos com assessores.

Foi útil?

Solução

Esse evento é apenas subscrever e cancelar a assinatura de um outro evento. Se você deseja que seus assinantes (e única seus assinantes - e não aqueles separadas para o outro evento) para ser chamado, você vai precisar para manter a preensão de seus assinantes separadamente. Por exemplo, você pode alterar o código para algo como:

private EventHandler canExecuteChanged;

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

Outras dicas

Eu acho que você tem eventos confundidos com os delegados. Somente a classe expondo o evento pode levantá-lo ... Outros só podem subscrever-unsubscribe a ele. Se você está chamando o evento de dentro da classe declarando o evento, ele deve funcionar como um delegado regular.

A melhor página que pude encontrar sobre Eventos vs Delegados . Leia-se ..

Você pode postar um trecho maior .. algo parece errado ..

assassino Atualização

Eu acho que finalmente ver o seu problema e como resolvê-lo. Resposta curta: Ele não sabe o nome do delegado para invocar se você escrever seus próprios assessores. Se você não fizer isso .. o compilador acrescenta o delegado privada de nome conhecido e, portanto, é capaz de chamá-lo

mostra esse trecho de código que quero dizer. Este artigo MSDN me mostrou o luz. Ótima pergunta cara .. Eu perdi 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!");
        }
}

Ok, eu descobri que se eu quiser acionar esse evento que você tem que fazer:

CommandManager.InvalidateRequerySuggested();.

Você tem que invocar os eventos subjacentes diretamente. No seu caso, parece que isso seria:

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

/ EDIT: Ok, eu não percebi que CommandManager é uma classe quadro. Neste caso, você obviamente não quero fazer o que eu tenho proposto. A solução de Jon é o ponto: Você tem que manter o controle de seu próprio evento e invocar que (por exemplo, como um delegado). De acordo com o exemplo de Jon, invocação ficaria assim:

canExecuteChanged(sender, EventArgs.Empty);

wow, apenas teve problemas semelhantes. A resposta que me ajudou a entender um pouco como O Gishu .

Também a partir do # especificações C, http: // www. microsoft.com/en-us/download/details.aspx?id=7029 , em "10.8.1 campo-like eventos" que diz "ao compilar um campo-like evento, o compilador cria automaticamente armazenamento para manter o delegado, "

especificações também diz:

Assim, uma declaração de instância de evento do formulário:

class X
{
   public event D Ev;
}

poderia ser compilado para 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; }
      }
   }
}

Se você fazer algo como o código abaixo, os compila compilador-lo com êxito:

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 você adicionar acessores para ss acima, não irá 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();
        }
    }
}

Existem dois tipos de eventos demonstraram aqui

  1. O campo-like eventos => podemos invocar
  2. eventos com assessores => não podemos invocar (não pode encontrar isso em especificações porquê, talvez eu perdi) (e só estava testando isso no Visual Studio 2005, e as especificações foi o último, eu acho)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top