Lançar um evento que tem acessores
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.
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
- O campo-like eventos => podemos invocar
- 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)