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. A substituição dos metadados permite modificar as características da propriedade de dependência herdada para corresponder aos requisitos específicos da subclasse.

Importante

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

Tela de fundo

Uma classe que define uma propriedade de dependência pode especificar suas características em PropertyMetadata ou 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 de propriedade de dependência. Quando os metadados não são especificados durante o registro, o sistema de propriedades 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 de 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 dentro de 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 derivada substitui os metadados de uma propriedade de dependência herdada da classe TropicalAquariumAquariumbase . O tipo de metadados é FrameworkPropertyMetadata, que oferece 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 em 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 Aquarium
    Inherits DependencyObject

    ' Register a dependency property with the specified property name,
    ' property type, owner type, and property metadata.
    Public Shared ReadOnly AquariumGraphicProperty As DependencyProperty =
        DependencyProperty.Register(
            name:="AquariumGraphic",
            propertyType:=GetType(Uri),
            ownerType:=GetType(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 Property AquariumGraphic As Uri
        Get
            Return CType(GetValue(AquariumGraphicProperty), Uri)
        End Get
        Set
            SetValue(AquariumGraphicProperty, Value)
        End Set
    End Property

End Class
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);
    }
}
Public Class TropicalAquarium
    Inherits Aquarium

    ' Static constructor.
    Shared Sub New()
        ' Create a new metadata instance with a modified default value.
        Dim newPropertyMetadata As New FrameworkPropertyMetadata(
            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:=GetType(TropicalAquarium),
            typeMetadata:=newPropertyMetadata)
    End Sub

End Class

Confira também