Metadados da 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 características de reflexão ou CLR (Common Language Runtime) geral. 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 pela propriedade de dependência herdada. E, se você adicionar sua classe como proprietário de uma propriedade de dependência, poderá substituir os metadados da propriedade de dependência herdada.

Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em construção.

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 para uma propriedade de dependência contém os seguintes tipos de informações:

  • O valor padrão da propriedade dependency, que é definido pelo sistema de propriedades quando nenhum outro valor se aplica, como um valor local, estilo ou herança. Para obter mais informações sobre a precedência de valor durante a atribuição em 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 e validação de propriedade de dependência.

  • Características da propriedade de dependência no nível da estrutura WPF (se a propriedade de dependência for uma propriedade de estrutura 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 de 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ário de uma propriedade de dependência.

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

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

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

As características de propriedade que são expostas por FrameworkPropertyMetadata às vezes são chamadas de sinalizadores. Ao criar uma instância, você tem a opção de passar uma FrameworkPropertyMetadata instância do tipo FrameworkPropertyMetadataOptions de enumeração para o FrameworkPropertyMetadata construtor. FrameworkPropertyMetadataOptions Permite especificar sinalizadores de metadados em combinação bitwise. Os FrameworkPropertyMetadata usos FrameworkPropertyMetadataOptions para manter o comprimento de sua assinatura do construtor razoável. No registro de propriedade de dependência, os sinalizadores de metadados definidos FrameworkPropertyMetadataOptions são expostos como FrameworkPropertyMetadataBoolean 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, talvez nem sempre seja 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. Talvez seja possível vincular os valores de propriedade por meio de 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 forma diferente de sua implementação base. Uma das características de um modelo de programação que oferece 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 propriedades de dependência.

  • Alterando as opções de metadados da propriedade da estrutura WPF. Normalmente, as opções de metadados são definidas durante o registro de uma nova propriedade de dependência, mas você pode reespecificá-las 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 os 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 de uma propriedade de dependência.

Um exemplo de uma propriedade de dependência 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 para true, mas preserva outros valores de false metadados herdados.

Como a maioria das propriedades de dependência existentes não são propriedades virtuais, sua implementação herdada faz sombra ao 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 um 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 valores em uma tabela e todos PropertyChangedCallback são invocados em uma alteração de propriedade. A ordem de retorno de chamada é determinada pela profundidade da classe, onde 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 um 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 adding não é derivada do tipo que registrou a propriedade dependency. Na chamada, a AddOwner classe de adição pode criar e atribuir metadados específicos de tipo para a propriedade de dependência herdada. Para ser um participante pleno no sistema de propriedade, através 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 de retorno da AddOwner chamada. Este campo deve ser um public static readonly campo do tipo DependencyProperty.

  • Um wrapper CLR que implementa e set acessaget. 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 e acessadores interagem com o sistema de propriedades subjacente por meio de DependencyObject.GetValue e setDependencyObject.SetValue chamadas, passando o identificador de propriedade de dependência como um parâmetro. Implemente o wrapper da mesma maneira 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 como 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 oferecem 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 dos 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 WPF para a propriedade anexada herdada, em instâncias da classe de substituição. Para obter mais informações, consulte Metadados de propriedade anexados

Observação

Sempre use RegisterAttached para registrar propriedades onde você especificar Inherits nos metadados. Embora a herança de valor de propriedade pareça 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), 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:

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

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

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

Confira também