Eventos de alteração de propriedade
Windows Presentation Foundation (WPF) define vários eventos que são gerados em resposta a uma alteração no valor de uma propriedade. Muitas vezes, a propriedade é uma propriedade de dependência. O evento em si às vezes é um evento roteado e às vezes é um evento CLR (Common Language Runtime) padrão. A definição do evento varia dependendo do cenário, porque algumas alterações de propriedade são mais apropriadamente roteadas através de uma árvore de elementos, enquanto outras alterações de propriedade geralmente são apenas de interesse para o objeto onde a propriedade foi alterada.
Identificando um evento de alteração de propriedade
Nem todos os eventos que relatam uma alteração de propriedade são explicitamente identificados como um evento de alteração de propriedade, seja em virtude de um padrão de assinatura ou de um padrão de nomenclatura. Geralmente, a descrição do evento na documentação do SDK indica se o evento está diretamente ligado a uma alteração de valor de propriedade e fornece referências cruzadas entre a propriedade e o evento.
Eventos RoutedPropertyChanged
Certos eventos usam um tipo de dados de evento e um delegado que são explicitamente usados para eventos de alteração de propriedade. O tipo de dados do evento é RoutedPropertyChangedEventArgs<T>e o delegado é RoutedPropertyChangedEventHandler<T>. Os dados de evento e o delegado têm um parâmetro de tipo genérico que é usado para especificar o tipo real da propriedade de alteração quando você define o manipulador. Os dados do evento contêm duas propriedades, OldValue e NewValue, que ambas são passadas como argumento de tipo nos dados do evento.
A parte "Roteado" do nome indica que o evento alterado de propriedade está registrado como um evento roteado. A vantagem de rotear um evento de propriedade alterada é que o nível superior de um controle pode receber eventos de propriedade alterada se as propriedades nos elementos filho (as partes compostas do controle) alterarem os valores. Por exemplo, você pode criar um controle que incorpore um controle RangeBase, como um Slider. Se o valor da propriedade Value for alterado na parte do controle deslizante, convém manipular essa alteração no controle pai em vez de na parte.
Como você tem um valor antigo e um valor novo, pode ser tentador usar esse manipulador de eventos como um validador para o valor da propriedade. No entanto, essa não é a intenção de design da maioria dos eventos de mudança de propriedade. Geralmente, os valores são fornecidos para que você possa agir sobre esses valores em outras áreas lógicas do seu código, mas na verdade alterar os valores de dentro do manipulador de eventos não é aconselhável e pode causar recursão não intencional dependendo de como seu manipulador é implementado.
Se sua propriedade for uma propriedade de dependência personalizada ou se você estiver trabalhando com uma classe derivada na qual você definiu o código de instanciação, há um mecanismo muito melhor para controlar alterações de propriedade que é incorporado ao sistema de propriedades WPF: os retornos de chamada do sistema de propriedades CoerceValueCallback e PropertyChangedCallback. Para obter mais detalhes sobre como pode usar o sistema de propriedades WPF para validação e coerção, consulte Retornos de chamada de propriedade de dependência e validação e Propriedades de dependência personalizadas.
Eventos DependencyPropertyChanged
Outro par de tipos que fazem parte de um cenário de evento de alteração de propriedade é DependencyPropertyChangedEventArgs e DependencyPropertyChangedEventHandler. Os eventos para essas alterações de propriedade não são roteados; são eventos CLR padrão. DependencyPropertyChangedEventArgs é um tipo de relatório de dados de eventos incomum porque não deriva de EventArgs; DependencyPropertyChangedEventArgs é uma estrutura, não uma classe.
Os eventos que usam DependencyPropertyChangedEventArgs e DependencyPropertyChangedEventHandler são um pouco mais comuns do que RoutedPropertyChanged
eventos. Um exemplo de um evento que usa esses tipos é IsMouseCapturedChanged.
Assim como RoutedPropertyChangedEventArgs<T>, DependencyPropertyChangedEventArgs também informa um valor antigo e novo para o imóvel. Além disso, as mesmas considerações sobre o que você pode fazer com os valores se aplicam; Geralmente, não é recomendável que você tente alterar os valores novamente no remetente em resposta ao evento.
Acionadores de propriedade
Um conceito intimamente relacionado com um evento de alteração de propriedade é um disparador de propriedade. Um gatilho de propriedade é criado dentro de um estilo ou modelo e permite que você crie um comportamento condicional com base no valor da propriedade onde o gatilho de propriedade é atribuído.
A propriedade para um disparador de propriedade deve ser uma propriedade de dependência. Pode ser (e frequentemente é) uma propriedade de dependência somente leitura. Um bom indicador para quando uma propriedade de dependência exposta por um controle é pelo menos parcialmente projetada para ser um gatilho de propriedade é se o nome da propriedade começar com "Is". As propriedades que têm esta nomenclatura são frequentemente uma propriedade de dependência booleana de leitura apenas, onde o cenário principal para a propriedade é relatar o estado de controlo que pode ter consequências para a interface do utilizador em tempo real e, portanto, é um candidato para disparar uma propriedade.
Algumas dessas propriedades também têm um evento dedicado de mudança de propriedade. Por exemplo, a propriedade IsMouseCaptured tem um evento de alteração de propriedade IsMouseCapturedChanged. A propriedade em si é somente leitura, com o seu valor ajustado pelo sistema de entrada, e o sistema de entrada aciona IsMouseCapturedChanged em cada alteração em tempo real.
Em comparação com um verdadeiro evento de alteração de propriedade, usar um disparador de propriedade para reagir a uma alteração de propriedade tem algumas limitações.
Os gatilhos de propriedade funcionam através de uma lógica de correspondência exata. Você especifica uma propriedade e um valor que indica o valor específico para o qual o gatilho agirá. Por exemplo: <Setter Property="IsMouseCaptured" Value="true"> ... </Setter>
. Devido a essa limitação, a maioria dos usos de gatilho de propriedade será para propriedades booleanas, ou propriedades que usam um valor de enumeração dedicado, onde o intervalo de valores possível é gerenciável o suficiente para definir um gatilho para cada caso. Ou gatilhos de propriedade podem existir apenas para valores especiais, como quando uma contagem de itens atinge zero, e não haveria nenhum gatilho que contabilizasse os casos em que o valor da propriedade muda de zero novamente (em vez de gatilhos para todos os casos, você pode precisar de um manipulador de eventos de código aqui ou um comportamento padrão que alterna de volta do estado de gatilho novamente quando o valor é diferente de zero).
A sintaxe do gatilho de propriedade é análoga a uma instrução "se" na programação. Se a condição do gatilho for verdadeira, o "corpo" do gatilho da propriedade será "executado". O "corpo" de um gatilho de propriedade não é código, é marcação. Essa marcação é limitada ao uso de um ou mais elementos Setter para definir outras propriedades do objeto onde o estilo ou modelo está sendo aplicado.
Para contrabalançar a condição "se" de um gatilho de propriedade que tem uma ampla variedade de valores possíveis, é geralmente aconselhável definir esse mesmo valor de propriedade como padrão usando um Setter. Desta forma, o setter Trigger contido terá precedência quando a condição de gatilho for verdadeira, e o Setter que não estiver dentro de um Trigger terá precedência sempre que a condição de gatilho for falsa.
Os gatilhos de propriedade geralmente são apropriados para cenários em que uma ou mais propriedades de aparência devem ser alteradas, com base no estado de outra propriedade no mesmo elemento.
Para saber mais sobre acionadores de propriedade, consulte Estilização e Modelagem.
Ver também
- Visão geral de eventos roteados
- Visão geral das propriedades de dependência
.NET Desktop feedback