Compartilhar via


Validação e Callbacks de Propriedade de Dependência

Este tópico descreve como criar propriedades de dependência usando implementações alternativas personalizadas para recursos relacionados a propriedade como validação de determinação, callbacks que são chamadas sempre que o valor efetivo da propriedade é alterado, e substituindo possíveis influências externas na determinação do valor. Este tópico também aborda situações em que é apropriado expandir os comportamentos padrões do sistema usando essas técnicas.

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

  • Pré-requisitos
  • Callbacks de validação
  • Callbacks de Valores Forçados e Eventos de Propriedades Alteradas
  • Coerção avançada e cenários de callback
  • Tópicos relacionados

Pré-requisitos

This topic assumes that you understand the basic scenarios of implementing a dependency property, and how metadata is applied to a custom dependency property. See Propriedades de Dependência Personalizada and Metadados de Propriedade de Dependência for context.

Callbacks de validação

Callbacks de validação podem ser atribuídas a uma propriedade de dependência quando você registrá-la pela primeira vez. Uma callback de validação não é parte da propriedade metadados; ela é uma entrada direta do método Register. Portanto, uma vez criada uma callback de validação para uma propriedade de dependência, ela não pode ser substituída por uma nova implementação.

As callbacks são implementadas de forma que elas recebam um valor de objeto. Elas retornam true se o valor fornecido é válido para a propriedade; caso contrário, elas retornam false. Pressupõe-se que a propriedade é do tipo correto para o tipo registrado com o sistema de propriedades, então a verificação de tipo dentro de callbacks normalmente não é feita. As callbacks são usadas pelo sistema de propriedades em uma variedade de operações diferentes. Isso inclui a inicialização de tipo inicial por valor padrão, por mudança programática invocando SetValue, ou por tentativa de substituir metadados com novo valor padrão fornecido. Se a callback de validação é chamada por qualquer uma dessas operações e retorna false, uma exceção será lançada. Criadores de aplicativo devem estar preparados para tratar essas exceções. Um uso comum de callbacks de validação é para validar valores de enumeração, ou para restrição de valores de números inteiros ou ponto-flutuante quando a propriedade define as medidas que devem ser zero ou maior que zero.

Callbacks de validação especificamente destinam-se a ser validadores de classe, e não validadores de instância. Os parâmetros de uma callback não transmitem um DependencyObject específico no qual as propriedades a serem validadas são definidas. Portanto, as callbacks de validação não são úteis para aplicar as possíveis "dependências" que podem influenciar o valor de uma propriedade, onde o valor específico de instância de uma propriedade é dependente de fatores como valores específicos de instância de outras propriedades, ou do estado de tempo de execução.

Este é o código de exemplo para um cenário de retorno de chamada muito simples de validação: Validando que uma propriedade que é tipada sistema autônomo a Double primitivos não PositiveInfinity ou NegativeInfinity.

Callbacks de Valores Forçados e Eventos de Propriedades Alteradas

Callbacks de valores forçados passam a instância específica de DependencyObject para propriedades, bem como implementações de PropertyChangedCallback que são chamadas pelo sistema de propriedades sempre que o valor de uma propriedade de dependência é alterado. Usando essas duas callbacks em combinação, você pode criar uma série de propriedades nos elementos em que alterações em uma propriedade forçará uma coerção ou reavaliação de outra propriedade.

Um cenário típico para usar uma ligação de propriedades de dependência é quando você tem um interface do usuário orientada a propriedades onde o elemento contém uma propriedade para o valor mínimo e uma para o máximo, e uma terceira propriedade para o valor real ou atual. Aqui, se o máximo foi ajustado de tal forma que o valor atual excedeu o novo máximo, você gostaria de forçar o valor atual a ser não maior que o novo máximo, e um relacionamento análogo para mínimo e atual.

A seguir está um breve exemplo de código para apenas uma das três propriedades de dependência que ilustram esse relacionamento. O exemplo mostra como a propriedade CurrentReading de um conjunto Min/Máx./Atual de propriedades *Reading relacionadas é registrada. Ele usa a validação como mostrado na seção anterior.

A callback de propriedade alterada para Atual é usada para encaminhar a alteração para outras propriedades dependentes, invocando explicitamente as callbacks de valores forçados que estão registradas para as outras propriedades:

A callback de valores forçados verifica os valores das propriedades das quais a propriedade atual é potencialmente dependente, e força o valor atual se necessário:

ObservaçãoObservação:

Valores padrão das propriedades não são forçados. Um valor da propriedade igual ao valor padrão pode ocorrer se um valor da propriedade ainda tem inicial padrão , ou por meio de limpeza outros valores com ClearValue.

As callbacks de valores forçados e de propriedade alterada fazem parte da propriedade metadados. Portanto, você pode alterar as callbacks para uma determinada propriedade de dependência conforme ela existe em um tipo que você derivar do tipo que possui a propriedade de dependência, substituindo os metadados para essa propriedade no seu tipo.

Coerção avançada e cenários de callback

Restrições e Valores desejados

As callbacks CoerceValueCallback serão usadas pelo sistema de propriedades para forçar um valor de acordo com a lógica que você declarar, mas um valor forçado de uma propriedade definida localmente ainda manterá um "valor desejado" internamente. Se as restrições são baseadas em outros valores de propriedades que podem ser alteradas dinamicamente durante o ciclo de vida do aplicativo, as restrições de coerção são alteradas dinamicamente também, e a propriedade restrita poderá alterar seu valor para chegar o mais perto possível do valor desejado dadas as novas restrições. O valor se tornará o valor desejado se todas as restrições são respeitadas. Você pode potencialmente criar algumas situações de dependência bastante complicadas se você tiver várias propriedades que são dependentes entre si de maneira circular. Por exemplo, no cenário de Min/Máx/Atual, você poderia optar por permitir que o usuáro definisse o mínimo e máximo. Nesse caso, talvez fosse preciso forçar que o máximo é sempre maior que o mínimo e vice-versa. Mas se aquela coerção estiver ativa, e o máximo é forçado a mínimo, isso deixa Atual em um estado inválido, porque ele é dependente de ambos e é restrito ao intervalo entre os valores, que é zero. Então, se máximo ou mínimo são ajustados, Atual parecerá "seguir" um dos valores, porque o valor desejado de Atual ainda está armazenado e está tentando atingir o valor desejado conforme as restrições são relaxadas.

Não há nada tecnicamente errado com dependências complexas, mas elas podem causar uma queda no desempenho se elas exigem um grande número de reavaliações, e também podem ser confusas para os usuários se eles afetam diretamente a interface do usuário. Tenha cuidado com callbacks de propriedade alterada e de valores forçados e certifique-se que a coerção que está sendo tentada pode ser tratada com o mínimo de ambiguidade possível e não é exageradamente restritiva. Este SDK inclui um (PropertyChanged e CoerceValue retornos de chamada de exemplo) de exemplo que deliberadamente ilustra o que não é necessariamente uma recomendação para coerção, com várias propriedades de dependência inter-relacionadas e algumas apresentações de interface do usuário. Você deve fazer experiências com esse exemplo como uma maneira de ilustrar os problemas de restrição, bem como o conceito de valor desejado explicado aqui.

Usando Valores Forçados para Cancelar Alterações de Valor

O sistema de propriedades tratará qualquer CoerceValueCallback que retorna o valor UnsetValue como um caso especial. Nesse caso especial significa que a alteração de propriedade que resultou em CoerceValueCallback sendo chamada deve ser rejeitada pelo sistema de propriedades, e que em vez disso o sistema de propriedades deve relatar qualquer valor anterior que a propriedade tinha. Esse mecanismo pode ser útil para verificar que alterações a uma propriedade que foi iniciadas de forma assíncrona são ainda válidas para o estado atual do objeto, e eliminar as alterações se não forem. Outro cenário possível é que você pode seletivamente suprimir um valor dependendo de qual componente para determinação do valor de propriedade é responsável pelo valor que está sendo relatado. Para fazer isso, você pode usar o DependencyProperty passado na callback e o identificador de propriedade como entrada para GetValueSource, e em seguida processar o ValueSource.

Consulte também

Conceitos

Visão geral sobre propriedades de dependência

Metadados de Propriedade de Dependência

Propriedades de Dependência Personalizada