Partilhar via


Metadados de propriedade de dependência (WPF .NET)

O sistema de propriedades do Windows Presentation Foundation (WPF) inclui um sistema de relatório de metadados de propriedade de dependência. As informações disponíveis por meio do sistema de relatório de metadados excedem o que está disponível por meio de reflexão ou características gerais de CLR (Common Language Runtime). Ao registrar uma propriedade de dependência, você tem a opção de criar e atribuir metadados a ela. Se você derivar de uma classe que define uma propriedade de dependência, poderá substituir os metadados da propriedade de dependência herdada. E, se você adicionar sua classe como proprietária de uma propriedade de dependência, poderá substituir os metadados da propriedade de dependência herdada.

Pré-requisitos

O artigo pressupõe um conhecimento básico das propriedades de dependência e que você leu Visão geral das propriedades de dependência. Para seguir os exemplos neste artigo, é útil se você estiver familiarizado com XAML (Extensible Application Markup Language) e souber como escrever aplicativos WPF.

Como os metadados são usados

Você pode consultar metadados de propriedade de dependência para examinar as características de uma propriedade de dependência. Quando o sistema de propriedades processa uma propriedade de dependência, ele acessa seus metadados. O objeto de metadados de uma propriedade de dependência contém os seguintes tipos de informações:

  • O valor padrão da propriedade de dependência, que é definido pelo sistema de propriedades quando nenhum outro valor se aplica, como um valor local, de estilo ou de herança. Para obter mais informações sobre a precedência de valor durante a atribuição de tempo de execução de valores de propriedade de dependência, consulte Precedência de valor de propriedade de dependência.

  • Referências a retornos de chamada de valor de coerção e retornos de chamada de alteração de propriedade no tipo de proprietário. Você só pode obter referências a retornos de chamada que tenham um public modificador de acesso ou estejam dentro do escopo de acesso permitido. Para obter mais informações sobre retornos de chamada de propriedade de dependência, consulte Retornos de chamada de propriedade de dependência e validação.

  • Características da propriedade de dependência no nível da estrutura do WPF (se a propriedade de dependência for uma propriedade da estrutura do WPF). Os processos do WPF, como o mecanismo de layout da estrutura e a lógica de herança de propriedade, consultam metadados no nível da estrutura do WPF. Para obter mais informações, consulte Metadados da propriedade do Framework.

APIs de metadados

A PropertyMetadata classe armazena a maioria dos metadados usados pelo sistema de propriedades. As instâncias de metadados podem ser criadas e atribuídas por:

  • Tipos que registram propriedades de dependência com o sistema de propriedades.

  • Tipos que herdam de uma classe que define uma propriedade de dependência.

  • Tipos que se adicionam como proprietários de uma propriedade de dependência.

Se um tipo registrar uma propriedade de dependência sem especificar metadados, o sistema de propriedades atribuirá um PropertyMetadata objeto com valores padrão para esse tipo à propriedade de dependência.

Para recuperar metadados para uma propriedade de dependência, chame GetMetadata uma das sobrecargas no DependencyProperty identificador. Os metadados são retornados como um PropertyMetadata objeto.

Classes de metadados mais específicas, derivadas de PropertyMetadata, existem para diferentes áreas arquitetônicas. Por exemplo, UIPropertyMetadata dá suporte a relatórios de animação e FrameworkPropertyMetadata dá suporte a propriedades de estrutura do WPF. As propriedades de dependência também podem ser registradas com as PropertyMetadata classes derivadas. Embora GetMetadata retorne um PropertyMetadata objeto, quando aplicável, você pode converter em um tipo derivado para examinar propriedades específicas do tipo.

As características de propriedade expostas por FrameworkPropertyMetadata às vezes são chamadas de sinalizadores. Ao criar uma FrameworkPropertyMetadata instância, você tem a opção de passar uma instância do tipo FrameworkPropertyMetadataOptions de enumeração para o FrameworkPropertyMetadata construtor. FrameworkPropertyMetadataOptions Permite especificar sinalizadores de metadados em combinação bit a bit. Os FrameworkPropertyMetadata usos FrameworkPropertyMetadataOptions para manter o comprimento de sua assinatura de construtor razoável. No registro de propriedade de dependência, os sinalizadores de metadados que você define FrameworkPropertyMetadataOptions são expostos como Boolean FrameworkPropertyMetadata propriedades, em vez de uma combinação bit a bit de sinalizadores, para tornar a consulta de características de metadados mais intuitiva.

Substituir ou criar novos metadados?

Ao herdar uma propriedade de dependência, você tem a opção de alterar as características da propriedade de dependência substituindo seus metadados. No entanto, nem sempre é possível realizar seu cenário de propriedade de dependência substituindo metadados e, às vezes, é necessário definir uma propriedade de dependência personalizada em sua classe com novos metadados. As propriedades de dependência personalizadas têm os mesmos recursos que as propriedades de dependência definidas pelos tipos WPF. Para obter mais informações, consulte Propriedades de dependência personalizadas.

Uma característica de uma propriedade de dependência que você não pode substituir é seu tipo de valor. Se uma propriedade de dependência herdada tiver o comportamento aproximado necessário, mas seu cenário exigir um tipo de valor diferente, considere implementar uma propriedade de dependência personalizada. Você pode vincular os valores de propriedade por meio da conversão de tipo ou outra implementação em sua classe derivada.

Cenários para substituir metadados

Exemplos de cenários para substituir metadados de propriedade de dependência existentes são:

  • Alterar o valor padrão, que é um cenário comum.

  • Alterar ou adicionar retornos de chamada de alteração de propriedade, o que pode ser necessário se uma propriedade de dependência herdada interagir com outras propriedades de dependência de maneira diferente de sua implementação base. Uma das características de um modelo de programação que dá suporte a código e marcação é que os valores de propriedade podem ser definidos em qualquer ordem. Esse fator pode afetar a forma como você implementa retornos de chamada de alteração de propriedade. Para obter mais informações, consulte Retornos de chamada e validação de propriedade de dependência.

  • Alterando as opções de metadados de propriedade da estrutura do WPF. Normalmente, as opções de metadados são definidas durante o registro de uma nova propriedade de dependência, mas você pode especificá-las novamente em OverrideMetadata ou AddOwner chamadas. Para obter mais informações sobre como substituir metadados de propriedade de estrutura, consulte Especificando FrameworkPropertyMetadata. Para saber como definir opções de metadados de propriedade de estrutura ao registrar uma propriedade de dependência, consulte Propriedades de dependência personalizadas.

Observação

Como os retornos de chamada de validação não fazem parte dos metadados, eles não podem ser alterados substituindo metadados. Para obter mais informações, consulte Retornos de chamada de valor de validação.

Substituindo metadados

Ao implementar uma nova propriedade de dependência, você pode definir seus metadados usando sobrecargas do Register método. Se sua classe herdar uma propriedade de dependência, você poderá substituir valores de metadados herdados usando o OverrideMetadata método. Por exemplo, você pode usar OverrideMetadata para definir valores específicos do tipo. Para obter mais informações e exemplos de código, consulte Substituir metadados para uma propriedade de dependência.

Um exemplo de uma propriedade de dependência do WPF é Focusable. A FrameworkElement classe registra Focusable. A Control classe deriva de FrameworkElement, herda a Focusable propriedade de dependência e substitui os metadados da propriedade herdada. A substituição altera o valor da propriedade padrão de false para true, mas preserva outros valores de metadados herdados.

Como a maioria das propriedades de dependência existentes não são propriedades virtuais, sua implementação herdada sombreia o membro existente. Quando você substitui uma característica de metadados, o novo valor de metadados substitui o valor original ou eles são mesclados:

  • Para um DefaultValue, o novo valor substituirá o valor padrão existente. Se você não especificar a DefaultValue nos metadados de substituição, o valor virá do ancestral mais próximo especificado DefaultValue nos metadados.

  • Para um PropertyChangedCallback, a lógica de mesclagem padrão armazena todos os PropertyChangedCallback valores em uma tabela e todos são invocados em uma alteração de propriedade. A ordem de retorno de chamada é determinada pela profundidade da classe, em que um retorno de chamada registrado pela classe base na hierarquia seria executado primeiro.

  • Para um CoerceValueCallback, o novo valor substituirá o valor existente CoerceValueCallback . Se você não especificar a CoerceValueCallback nos metadados de substituição, o valor virá do ancestral mais próximo especificado CoerceValueCallback nos metadados.

Observação

A lógica de mesclagem padrão é implementada Merge pelo método. Você pode especificar a lógica de mesclagem personalizada em uma classe derivada que herda uma propriedade de dependência, substituindo Merge essa classe.

Adicionar uma classe como proprietário

Para "herdar" uma propriedade de dependência registrada em uma hierarquia de classe diferente, use o AddOwner método. Esse método normalmente é usado quando a classe de adição não é derivada do tipo que registrou a propriedade de dependência. AddOwner Na chamada, a classe de adição pode criar e atribuir metadados específicos do tipo para a propriedade de dependência herdada. Para ser um participante completo no sistema de propriedades, por meio de código e marcação, a classe de adição deve implementar estes membros públicos:

  • Um campo identificador de propriedade de dependência. O valor do identificador de propriedade de dependência é o valor retornado da AddOwner chamada. Esse campo deve ser um public static readonly campo do tipo DependencyProperty.

  • Um wrapper CLR que implementa get e set acessadores. Usando um wrapper de propriedade, os consumidores de propriedades de dependência podem obter ou definir valores de propriedade de dependência, assim como fariam com qualquer outra propriedade CLR. Os get acessadores and set interagem com o sistema de propriedades subjacente por meio DependencyObject.GetValue de chamadas and DependencyObject.SetValue , passando o identificador de propriedade de dependência como um parâmetro. Implemente o wrapper da mesma forma que faria ao registrar uma propriedade de dependência personalizada. Para obter mais informações, consulte Propriedades de dependência personalizadas

Uma classe que chama AddOwner tem os mesmos requisitos para expor o modelo de objeto da propriedade de dependência herdada que uma classe que define uma nova propriedade de dependência personalizada. Para obter mais informações, consulte Adicionar um tipo de proprietário para uma propriedade de dependência.

Metadados de propriedade anexados

No WPF, a maioria das propriedades anexadas relacionadas à interface do usuário em tipos WPF são implementadas como propriedades de dependência. As propriedades anexadas implementadas como propriedades de dependência dão suporte a conceitos de propriedade de dependência, como metadados que as classes derivadas podem substituir. Os metadados de uma propriedade anexada geralmente não são diferentes de uma propriedade de dependência. Você pode substituir o valor padrão, os retornos de chamada de alteração de propriedade e as propriedades da estrutura do WPF para a propriedade anexada herdada, em instâncias da classe de substituição. Para obter mais informações, consulte Metadados de propriedade anexada

Observação

Sempre use RegisterAttached para registrar propriedades onde você especifica Inherits nos metadados. Embora a herança de valor de propriedade possa parecer funcionar para propriedades de dependência não anexadas, o comportamento de herança de valor para uma propriedade não anexada por meio de determinadas divisões objeto-objeto na árvore de tempo de execução é indefinido. A Inherits propriedade não é relevante para propriedades não anexadas. Para obter mais informações, consulte RegisterAttached(String, Type, Type, PropertyMetadata)o e a seção de comentários do Inherits.

Adicionar uma classe como proprietário de uma propriedade anexada

Para herdar uma propriedade anexada de outra classe, mas expô-la como uma propriedade de dependência não anexada em sua classe:

  • Chame AddOwner para adicionar sua classe como proprietária da propriedade de dependência anexada.

  • Atribua o valor retornado da AddOwner chamada a um public static readonly campo, para uso como o identificador de propriedade de dependência.

  • Defina um wrapper CLR, que adiciona a propriedade como um membro de classe e dá suporte ao uso de propriedade não anexada.

Confira também