Compartilhar via


Visão geral sobre eventos anexados

Extensible Application Markup Language (XAML) define um componente da linguagem e tipo de evento chamado evento anexado. O conceito de um evento anexado permite que você adicione um manipulador para um determinado evento a um elemento arbitrário em vez de a um elemento que realmente define ou herda o evento. Nesse caso, nem o objeto potencialmente lançando o evento nem a instância destino de tratamento definem ou são "donas" do evento.

Este tópico contém as seguintes seções.

  • Pré-requisitos
  • Sintaxe de evento anexado
  • Como o WPF implementa eventos anexados
  • Cenários para eventos anexados
  • Tratando um evento anexado no WPF
  • Definindo seus próprios eventos anexados como eventos roteados
  • Lançando um evento anexado do WPF
  • Tópicos relacionados

Pré-requisitos

Este tópico pressupõe que você leu Visão geral sobre eventos roteados e XAML Overview.

Sintaxe de evento anexado

Eventos anexados tem uma sintaxe XAML e um padrão de codificação que devem ser usados pelo código de apoio para oferecer suporte a utilização de eventos anexados.

Em sintaxe XAML o evento anexado é especificado não apenas por seu nome de evento, mas por seu tipo proprietário mais o nome do evento, separados por um ponto (.). Como o nome do evento é qualificado com o nome do seu tipo proprietário, a sintaxe de evento anexado permite que qualquer evento anexado seja anexado a qualquer elemento que pode ser instanciado.

Por exemplo, a sintaxe XAML para anexar um manipulador para um evento anexado NeedsCleaning personalizado é a seguinte:

<aqua:Aquarium Name="theAquarium" Height="600" Width="800" aqua:AquariumFilter.NeedsCleaning="WashMe"/>

Observe o prefixo aqua:; o prefixo é necessário nesse caso porque o evento anexado é um evento personalizado proveniente de um xmlns personalizado mapeado.

Como o WPF implementa eventos anexados

No WPF, eventos anexados são apoiados por um campo RoutedEvent e são roteados através da árvore depois que eles são gerados. Normalmente, a origem do evento anexado (o objeto que gera o evento) é uma origem de sistema ou de serviço, e o objeto que executa o código que gera o evento não é, portanto, parte direta da árvore do elemento.

Cenários para eventos anexados

No WPF, eventos anexados estão presentes em certas áreas de recursos onde há uma abstração em nível de serviço, como para os eventos ativados pela classe estática Mouse ou pela classe Validation. As classes que interagem com (ou usam) o serviço podem usar o evento via sintaxe de evento anexado, ou poderão escolher levantar o evento anexado como um evento roteado que faz parte de como a classe integra os recursos do serviço.

Embora o WPF defina uma variedade de eventos anexados, os cenários onde você irá usar ou manipular o evento anexado diretamente são muito limitados. Geralmente, o evento anexado tem uma finalidade arquitetural, mas é então encaminhado para um evento roteado não anexado (apoiado em um "wrapper" de eventos CLR).

Por exemplo, o evento anexado Mouse.MouseDown subjacente pode mais facilmente ser tratado em qualquer UIElement usando-se MouseDown no UIElement ao invés de lidar com a sintaxe de evento anexado em XAML ou em código. O evento anexado serve um propósito na arquitetura pois ele permite a expansão futura de dispositivos de entrada. O dispositivo hipotético só precisaria lançar Mouse.MouseDown para simular a entrada do mouse e não precisaria derivar de Mouse para fazer isso. No entanto, esse cenário envolve tratamento dos eventos em código, e o tratamento em XAML de eventos anexados não é relevante para esse cenário.

Tratando um evento anexado no WPF

O processo para tratar um evento anexado, e o código do manipulador que você vai escrever, é basicamente o mesmo que o para um evento roteado.

Em geral, um evento anexado WPF não é muito diferente de um evento roteado WPF. As diferenças são como o evento é originado e como ele é exposto por uma classe como um membro (o que também afeta a sintaxe de manipulação em XAML).

No entanto, conforme observado anteriormente, os eventos anexados WPF existentes não se destinam particularmente para tratamento no WPF. Com mais frequência, o objetivo do evento é permitir que um elemento composto relate um estado para uma elemento pai na composição, nesse caso o evento é gerado normalmente em código e também depende do tratamento por classe na classe pai relevante. Por exemplo, se espera que itens em um Selector gerem o evento anexado Selected, que é então tratado por classe pela classe Selector e, em seguida, potencialmente convertido pela classe Selector em um evento roteado diferente, SelectionChanged. Para obter mais informações sobre eventos roteados e tratamento por classe, consulte Marcando Eventos Roteados como Manipulados e Manipulação de Classes.

Definindo seus próprios eventos anexados como eventos roteados

Se você estiver derivando de classes base WPF comuns, você pode implementar seus próprios eventos anexados incluindo determinados métodos padrão em sua classe e usando métodos utilitários que já estão presentes nas classes base.

O padrão é:

  • Um método Add*Handler com dois parâmetros. O primeiro parâmetro deve identificar o evento, e o evento identificado deve corresponder a nomes com o * no nome do método. O segundo parâmetro é o manipulador de adicionar. O método deve ser público e estático, sem nenhuma valor de retorno.

  • Um método Remove*Handler com dois parâmetros. O primeiro parâmetro deve identificar o evento, e o evento identificado deve corresponder a nomes com o * no nome do método. O segundo parâmetro é o manipulador a ser removido. O método deve ser público e estático, sem nenhuma valor de retorno.

O método de acesso Add*Handler facilita o processamento do XAML quando atributos do manipulador de eventos anexados são declarados em um elemento. Os métodos Add*Handler e Remove*Handler também permitem acesso em código ao armazenamento do manipulador de eventos para o evento anexado.

Este padrão geral não é ainda preciso o suficiente para implementação prática em um framework, pois qualquer implementação de leitor XAML pode ter diferentes esquemas para identificar eventos subjacentes na linguagem e na arquitetura. Este é um dos motivos pelos quais o WPF implementa eventos anexados como eventos roteados; o identificador a ser usado para um evento (RoutedEvent) já está definido pelo sistema de eventos do WPF. Além disso, o roteamento de um evento é uma extensão natural da implementação no conceito XAML, em nível de linguagem, de um evento anexado.

A implementação de Add*Handler de um evento anexado WPF consiste em chamar AddHandler com o evento roteado e o manipulador como argumentos.

Essa estratégia de implementação e o sistema de eventos roteadas em geral restringem o tratamento de eventos anexados a classes derivadas de UIElement ou de ContentElement, pois apenas essas classes tem implementações de AddHandler.

Por exemplo, o código a seguir define o evento anexado NeedsCleaning na classe proprietária Aquarium, utilizando a estratégia WPF de eventos anexados de declarar o evento anexado como um evento roteado.

<aqua:Aquarium Name="theAquarium" Height="600" Width="800" aqua:AquariumFilter.NeedsCleaning="WashMe"/>

Observe que o método usado para estabelecer o campo identificador de evento anexado, RegisterRoutedEvent, é realmente o mesmo método usado para registrar um evento roteado não anexado. Todos os eventos anexados e eventos roteados são registrados em um espaço de armazenamento centralizado interno. Esta implementação do espaço de armazenamento de eventos permite a consideração conceitual de "eventos como interface" que é abordada em Visão geral sobre eventos roteados.

Lançando um evento anexado do WPF

Geralmente não é necessário lançar eventos anexados existentes definidos pelo WPF a partir do seu código. Esses eventos seguem o modelo conceitual geral de "serviço", e classes de serviço como InputManager são responsáveis por lançar os eventos.

No entanto, se você estiver definindo um evento anexado personalizado com base no modelo do WPF de basear eventos anexados em RoutedEvent, você pode usar RaiseEvent para gerar um evento de qualquer UIElement ou ContentElement. Gerar um evento roteado (anexado ou não) requer que você declare um determinado elemento na árvore de elementos como a fonte do evento; a fonte é relatada como o "chamador" de RaiseEvent. Determinar qual elemento é relatado como fonte do evento na árvore é responsabilidade do serviço

Consulte também

Conceitos

Visão geral sobre eventos roteados

Terminologia de sintaxe XAML

XAML e classes personalizadas