Eventos de Alteração de Propriedades
Windows Presentation Foundation (WPF) define vários eventos que são criados em resposta a uma alteração no valor de uma propriedade. Geralmente a propriedade é uma propriedade de dependência . O evento mesmo é às vezes, um evento roteado e é às vezes, um evento common language runtime (CLR) padrão. A definição do evento varia dependendo do cenário, porque algumas alterações de propriedades são mais adequadamente roteadas pela árvore de elemento, enquanto outras alterações de propriedades são geralmente somente de interesse para o objeto onde a propriedade alterou.
Identificar um Evento de Alteração da Propriedade
Nem todos os eventos que reportam uma alteração de propriedades são explicitamente identificados como um evento de alteração de propriedade, tanto em virtude de um padrão de assinatura ou um padrão de nomeação. Geralmente, a descrição do evento na documentação do software development kit (SDK) indica se o evento está diretamente vinculado a uma alteração no valor da propriedade e fornece referências cruzadas entre a propriedade e evento.
Eventos RoutedPropertyChanged
Determinados eventos usam um tipo de dados de eventos e representante explicitamente usados para eventos de alteração de propriedades. O tipo de dados de evento é RoutedPropertyChangedEventArgs<T>, e o representante é RoutedPropertyChangedEventHandler<T>. Os dados do evento e representante têm um parâmetro de tipo genérico que é usado para especificar o real tipo da propriedade a alterar quando você define o manipulador. Os dados do evento contém duas propriedades, OldValue e NewValue, que são então passadas como o argumento Tipo nos dados do evento.
A parte "Routed" do nome indica que o evento da propriedade alterada está registrada como um evento roteado. A vantagem do roteamento de 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 (das partes compostas do controle) alterar valores. Por exemplo, você pode criar um controle que incorpora um controle RangeBase como um Slider. Se o valor da propriedade Value se altera na parte do controle deslizante, convém tratar essa alteração na controle pai em vez de na parte.
Como você possui um valor antigo e um novo valor, talvez seja tentador usar este manipulador de eventos como uma validação para o valor da propriedade. No entanto, essa não é a intenção de estruturação da maioria dos eventos de propriedade alterada. Geralmente, os valores são fornecidos para que você pode atuar nesses valores em outras áreas de lógica do seu código, mas, na verdade, alterando os valores de dentro do manipulador de eventos não é aconselhável, podendo causar a recursão não intencional dependendo de como seu manipulador é implementado.
Se sua propriedade é uma propriedade de dependência personalizadas, ou se você estiver trabalhando com uma classe derivada em que você definiu o código a instanciação, há um muito melhor mecanismo para controlar alterações de propriedade que se baseia à WPF sistema de propriedades: propriedade sistema retornos de chamada CoerceValueCallback e PropertyChangedCallback. Para obter mais detalhes sobre como você pode usar o sistema de propriedade WPFpara validação e coerção, consulte Validação e Callbacks de Propriedade de Dependência e Propriedades de Dependência Personalizada.
Eventos DependencyPropertyChanged
Outro par de tipos que fazem parte de um cenário de evento de propriedade alterada é DependencyPropertyChangedEventArgs e DependencyPropertyChangedEventHandler. Eventos para que essas alterações de propriedade não são roteados; eles são o padrão de CLR eventos. DependencyPropertyChangedEventArgs é um evento incomuns de dados tipo de relatório porque não é derivado de EventArgs; DependencyPropertyChangedEventArgs é uma estrutura, não uma classe.
Eventos que usam DependencyPropertyChangedEventArgs e DependencyPropertyChangedEventHandler são um pouco mais comuns do que eventos RoutedPropertyChanged. Um exemplo de um evento que usa esses tipos é IsMouseCapturedChanged.
Como RoutedPropertyChangedEventArgs<T>, DependencyPropertyChangedEventArgs também relata um antigo e novo valor para a propriedade. Além disso, as mesmas considerações sobre o que se pode fazer com os valores se aplicam; geralmente, não se recomenda que você tente alterar os valores novamente no remetente em resposta ao evento.
Disparadores de propriedade
Um conceito fortemente relacionado a um evento de propriedade alterada é um disparador de propriedade. Um disparador de propriedade é criado em um estilo ou modelo e permite a criação de um comportamento condicional com base no valor da propriedade onde o disparador de propriedade é atribuído.
A propriedade para um disparador de propriedade deve ser uma propriedade de dependência. Ele pode ser (e frequentemente é) uma propriedade de dependência de somente leitura. Um bom indicador para quando um propriedade de dependência exposta por um controle é pelo menos parcialmente projetada para ser um disparador de propriedade é se o nome da propriedade começa com "É". Propriedades que têm esse nomeação são geralmente uma propriedade de dependência booleana para leitura somente onde o cenário primário para a propriedade está relatando estado do controle que pode ter consequências para a interface do usuário em tempo real e é, portanto, um candidato a disparador de propriedade.
Algumas dessas propriedades também possuem um evento de propriedade alterada dedicado. Por exemplo, a propriedade IsMouseCaptured possui um evento de propriedade alterada IsMouseCapturedChanged. A propriedade em si é somente leitura, com seu valor ajustado pelo sistema de entrada, e o sistema de entrada gera IsMouseCapturedChanged em cada alteração em tempo real.
Comparado a um verdadeiro evento de propriedade alterada, usar um disparador de propriedade para atuar em uma alteração de propriedade tem algumas limitações.
Disparadores de propriedade trabalham em uma correspondência exata lógica. Especifica-se uma propriedade e um valor que indica o valor específico no qual o disparador atuará. Por exemplo: <Setter Property="IsMouseCaptured" Value="true"> ... </Setter>. Por causa dessa limitação, a maioria dos usos dos disparadores de propriedades será para propriedades booleanas, ou propriedades que tomam um valor de enumeração dedicado, onde o intervalo de valores possível é suficientemente gerenciável para definir um disparador para cada ocorrência. Ou disparadores de propriedades podem existir somente para valores especiais, como quando uma contagem de itens chegar a zero, e não há nenhum disparador que responde pelos casos quando alterações no valor da propriedade se afastam de zero novamente (em vez de disparadores para todos os casos, talvez seja necessário um manipulador de eventos de código aqui, ou um comportamento padrão que alterna de volta ao estado do disparador novamente quando o valor é diferente de zero).
A sintaxe do disparador de propriedade é análoga a uma instrução "se" em programação. Se a condição de disparador for verdadeira, o "corpo" do disparador de propriedade é " executado ". O "corpo" de um disparador de propriedade não é código, é marcação. Aquela marcação está limitada a usar um ou mais elementos Setter para definir outras propriedades do objeto no qual o estilo ou modelo está sendo aplicado.
Para deslocar a condição "se" de um disparador de propriedade que possui uma ampla variedade de valores possíveis, é aconselhável geralmente definir aquele mesmo valor de propriedade a um padrão usando um Setter desse mesmo valor da propriedade. Dessa forma, o setter contido em Trigger terá precedência quando a condição do disparador for verdadeira, e o Setter que não está dentro um Trigger terá precedência sempre que a condição do disparador for falsa.
Disparadores de propriedade são geralmente apropriadas para situações em que uma ou mais propriedades de aparência devem alterar, com base no estado de uma outra propriedade no mesmo elemento.
Para saber mais sobre disparadores de propriedade, consulte Styling and Templating.