Visão geral de eventos anexados
XAML (Extensible Application Markup Language) define um componente de linguagem e um tipo de evento chamado evento anexado. O conceito de um evento anexado permite adicionar 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 acionando o evento nem a instância de tratamento de destino define ou de outra forma "possui" o evento.
Pré-requisitos
Este tópico pressupõe que você leu Visão Geral de Eventos Roteados e XAML no WPF.
Sintaxe de evento anexada
Os eventos anexados têm uma sintaxe XAML e um padrão de codificação que deve ser usado pelo código de backup para dar suporte ao uso de evento anexado.
Na sintaxe XAML, o evento anexado é especificado não apenas pelo nome do evento, mas pelo seu tipo proprietário mais o nome do evento, separado por um ponto (.). Como o nome do evento é qualificado com o nome de seu tipo proprietário, a sintaxe de evento anexado permite que qualquer evento anexado seja utilizado em qualquer elemento que possa ser instanciado.
Por exemplo, a seguir está a sintaxe XAML para anexar um manipulador a um evento personalizado NeedsCleaning
anexado:
<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 que vem de um xmlns mapeado personalizado.
Como o WPF implementa eventos anexados
No WPF, os eventos anexados são apoiados por um campo de RoutedEvent e percorrem a árvore depois de serem acionados. Normalmente, a origem do evento anexado (o objeto que aciona o evento) é uma fonte de serviço ou sistema e o objeto que executa o código que aciona o evento não é, portanto, uma parte direta da árvore de elementos.
Cenários para eventos anexados
No WPF, os eventos anexados estão presentes em determinadas áreas de recursos em que há abstração no nível do serviço, como para os eventos habilitados pela classe Mouse estática ou pela classe Validation. Classes que interagem ou usam o serviço podem usar o evento na sintaxe de evento anexada ou podem optar por exibir o evento anexado como um evento roteado que faz parte de como a classe integra os recursos do serviço.
Embora o WPF defina vários eventos anexados, os cenários em que você usará ou manipulará o evento anexado diretamente são muito limitados. Geralmente, o evento anexado serve a uma finalidade de arquitetura, mas é encaminhado para um evento roteado não anexado (com backup com um evento CLR "wrapper").
Por exemplo, o evento anexado subjacente Mouse.MouseDown pode ser tratado com mais facilidade em qualquer UIElement ao usar MouseDown nesse UIElement, em vez de lidar com a sintaxe de evento anexado em XAML ou código. O evento anexado serve a uma finalidade na arquitetura porque permite a expansão futura de dispositivos de entrada. O dispositivo hipotético só precisaria gerar Mouse.MouseDown para simular a entrada do mouse e não precisaria derivar de Mouse para fazê-lo. No entanto, esse cenário envolve o tratamento de código dos eventos e o tratamento XAML do evento anexado não é relevante para esse cenário.
Manipulação de um Evento Anexado no WPF
O processo para lidar com um evento anexado e o código do manipulador que você escreverá é basicamente o mesmo de um evento roteado.
Em geral, um evento anexado do WPF não é muito diferente de um evento roteado do WPF. As diferenças são como o evento é originado e como ele é exposto por uma classe como membro (o que também afeta a sintaxe do manipulador XAML).
No entanto, conforme observado anteriormente, os eventos anexados do WPF existentes não se destinam particularmente à manipulação no WPF. Com mais frequência, a finalidade do evento é permitir que um elemento compostado comunique um estado a um elemento pai durante a composição, caso em que o evento geralmente é gerado no código e também depende da manipulação de classe na classe pai em questão. Por exemplo, espera-se que os itens dentro de um Selector acionem o evento Selected anexado, que é então tratado 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 manipulação de classe, consulte Marcando Eventos Roteados Como Manipulados e Manipulação de Classe.
Definindo seus próprios eventos anexados como eventos roteados
Se você estiver derivando de classes base comuns do WPF, poderá 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 é o seguinte:
Um método AddEventNameHandler com dois parâmetros. O primeiro parâmetro é a instância à qual o manipulador de eventos é adicionado. O segundo parâmetro é o manipulador de eventos a ser adicionado. O método deve ser
public
estatic
, sem nenhum valor retornado.Um método para remover o manipulador de evento com dois parâmetros. O primeiro parâmetro é a instância da qual o manipulador de eventos é removido. O segundo parâmetro é o manipulador de eventos a ser removido. O método deve ser
public
estatic
, sem nenhum valor retornado.
O método Adicionardo Manipuladordo EventName facilita o processamento XAML quando atributos de manipulador de eventos anexados são declarados em um elemento. Os métodos AddEventNameHandler e RemoveEventNameHandler também permitem o acesso de código ao repositório de manipuladores de eventos para o evento anexado.
Esse padrão geral ainda não é preciso o suficiente para implementação prática em uma estrutura, pois qualquer implementação de leitor XAML determinada pode ter esquemas diferentes para identificar eventos subjacentes na linguagem e arquitetura de suporte. Esse é 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 de implementação no conceito de um evento associado no nível de linguagem XAML.
O Adicionarimplementação do Manipulador deeventName para um evento anexado do WPF consiste em chamar o AddHandler com o evento roteado e o manipulador como argumentos.
Essa estratégia de implementação e o sistema de eventos roteados em geral restringem a manipulação de eventos anexados a classes derivadas de UIElement ou a classes derivadas de ContentElement, pois somente essas classes têm implementações de AddHandler.
Por exemplo, o código a seguir define o evento anexado NeedsCleaning
na classe de proprietário Aquarium
, usando a estratégia de evento anexado do WPF para declarar o evento como um evento roteado.
public static readonly RoutedEvent NeedsCleaningEvent = EventManager.RegisterRoutedEvent("NeedsCleaning", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(AquariumFilter));
public static void AddNeedsCleaningHandler(DependencyObject d, RoutedEventHandler handler)
{
UIElement uie = d as UIElement;
if (uie != null)
{
uie.AddHandler(AquariumFilter.NeedsCleaningEvent, handler);
}
}
public static void RemoveNeedsCleaningHandler(DependencyObject d, RoutedEventHandler handler)
{
UIElement uie = d as UIElement;
if (uie != null)
{
uie.RemoveHandler(AquariumFilter.NeedsCleaningEvent, handler);
}
}
Public Shared ReadOnly NeedsCleaningEvent As RoutedEvent = EventManager.RegisterRoutedEvent("NeedsCleaning", RoutingStrategy.Bubble, GetType(RoutedEventHandler), GetType(AquariumFilter))
Public Shared Sub AddNeedsCleaningHandler(ByVal d As DependencyObject, ByVal handler As RoutedEventHandler)
Dim uie As UIElement = TryCast(d, UIElement)
If uie IsNot Nothing Then
uie.AddHandler(AquariumFilter.NeedsCleaningEvent, handler)
End If
End Sub
Public Shared Sub RemoveNeedsCleaningHandler(ByVal d As DependencyObject, ByVal handler As RoutedEventHandler)
Dim uie As UIElement = TryCast(d, UIElement)
If uie IsNot Nothing Then
uie.RemoveHandler(AquariumFilter.NeedsCleaningEvent, handler)
End If
End Sub
Observe que o método usado para estabelecer o campo do identificador de evento anexado, RegisterRoutedEvent, é, na verdade, o mesmo método usado para registrar um evento roteado não anexado. Eventos anexados e eventos roteados são registrados em um repositório interno centralizado. Essa implementação do repositório de eventos permite a consideração conceitual "eventos como interface" discutida em Visão Geral de Eventos Roteados.
Criando um evento anexado do WPF
Normalmente, você não precisa disparar eventos associados definidos pelo WPF existentes 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 gerar os eventos.
No entanto, se você estiver definindo um evento anexado personalizado com base no modelo do WPF de basear eventos anexados em RoutedEvent, poderá usar RaiseEvent para gerar um evento anexado de qualquer UIElement ou ContentElement. Gerar um evento roteado (anexado ou não) requer que você declare um elemento específico na árvore de elementos como a origem do evento; essa fonte é relatada como o chamador RaiseEvent. Determinar qual elemento é relatado como a origem na árvore é responsabilidade do seu serviço
Consulte também
- Visão geral de eventos roteados
- sintaxe XAML em detalhes
- XAML e Classes Personalizadas para WPF
.NET Desktop feedback