Como substituir metadados para uma propriedade de dependência (WPF .NET)

Quando você deriva de uma classe que define uma propriedade de dependência, você herda a propriedade de dependência e seus metadados. Este artigo descreve como você pode substituir os metadados de uma propriedade de dependência herdada chamando o OverrideMetadata método. Substituir os metadados permite modificar as características da propriedade de dependência herdada para corresponder aos requisitos específicos da subclasse.

Tela de fundo

Uma classe que define uma propriedade de dependência pode especificar suas características em PropertyMetadata ou em um de seus tipos derivados, como FrameworkPropertyMetadata. Uma dessas características é o valor padrão de uma propriedade de dependência. Muitas classes que definem propriedades de dependência, especificam metadados de propriedade durante o registro da propriedade de dependência. Quando os metadados não são especificados durante o registro, o sistema de propriedades do WPF atribui um PropertyMetadata objeto com valores padrão. As classes derivadas que herdam propriedades de dependência por meio da herança de classe têm a opção de substituir os metadados originais de qualquer propriedade de dependência. Dessa forma, as classes derivadas podem modificar seletivamente as características da propriedade de dependência para atender aos requisitos da classe. Ao chamar OverrideMetadata(Type, PropertyMetadata), uma classe derivada especifica seu próprio tipo como o primeiro parâmetro e uma instância de metadados como o segundo parâmetro.

Uma classe derivada que substitui metadados em uma propriedade de dependência deve fazer isso antes que a propriedade seja colocada em uso pelo sistema de propriedades. Uma propriedade de dependência é colocada em uso quando qualquer instância da classe que registra a propriedade é instanciada. Para ajudar a atender a esse requisito, a classe derivada deve chamar OverrideMetadata seu construtor estático. Substituir os metadados de uma propriedade de dependência depois que seu tipo de proprietário é instanciado não gerará exceções, mas resultará em comportamentos inconsistentes no sistema de propriedades. Além disso, um tipo derivado não pode substituir os metadados de uma propriedade de dependência mais de uma vez, e as tentativas de fazer isso gerarão uma exceção.

Exemplo

No exemplo a seguir, a classe TropicalAquarium derivada substitui os metadados de uma propriedade de dependência herdada da classe Aquariumbase. O tipo de metadados é FrameworkPropertyMetadata, que dá suporte a características de estrutura WPF relacionadas à interface do usuário, como AffectsRender. A classe derivada não substitui o sinalizador herdado AffectsRender , mas atualiza o valor padrão de instâncias de AquariumGraphic classe derivadas.

public class Aquarium : DependencyObject
{
    // Register a dependency property with the specified property name,
    // property type, owner type, and property metadata.
    public static readonly DependencyProperty AquariumGraphicProperty =
        DependencyProperty.Register(
          name: "AquariumGraphic",
          propertyType: typeof(Uri),
          ownerType: typeof(Aquarium),
          typeMetadata: new FrameworkPropertyMetadata(
              defaultValue: new Uri("http://www.contoso.com/aquarium-graphic.jpg"),
              flags: FrameworkPropertyMetadataOptions.AffectsRender)
        );

    // Declare a read-write CLR wrapper with get/set accessors.
    public Uri AquariumGraphic
    {
        get => (Uri)GetValue(AquariumGraphicProperty);
        set => SetValue(AquariumGraphicProperty, value);
    }
}
public class TropicalAquarium : Aquarium
{
    // Static constructor.
    static TropicalAquarium()
    {
        // Create a new metadata instance with a modified default value.
        FrameworkPropertyMetadata newPropertyMetadata = new(
            defaultValue: new Uri("http://www.contoso.com/tropical-aquarium-graphic.jpg"));

        // Call OverrideMetadata on the dependency property identifier.
        // Pass in the type for which the new metadata will be applied
        // and the new metadata instance.
        AquariumGraphicProperty.OverrideMetadata(
            forType: typeof(TropicalAquarium),
            typeMetadata: newPropertyMetadata);
    }
}

Confira também