Compartir a través de


Cómo invalidar los metadatos de una propiedad de dependencia

Cuando se deriva de una clase que define una propiedad de dependencia, hereda la propiedad de dependencia y sus metadatos. En este artículo se describe cómo puede invalidar los metadatos de una propiedad de dependencia heredada llamando al OverrideMetadata método . Sobrescribir los metadatos permite modificar las características de la propiedad dependiente heredada para que coincidan con los requisitos específicos de la subclase.

Contexto

Una clase que define una propiedad de dependencia puede especificar sus características en PropertyMetadata o en uno de sus tipos derivados, como FrameworkPropertyMetadata. Una de esas características es el valor predeterminado de una propiedad de dependencia. Muchas clases que definen propiedades de dependencia, especifican metadatos de propiedad durante el registro de propiedades de dependencia. Cuando no se especifican metadatos durante el registro, el sistema de propiedades de WPF asigna un PropertyMetadata objeto con valores predeterminados. Las clases derivadas que heredan las propiedades de dependencia a través de la herencia de clases tienen la opción de invalidar los metadatos originales de cualquier propiedad de dependencia. De este modo, las clases derivadas pueden modificar selectivamente las características de propiedad de dependencia para cumplir los requisitos de clase. Al llamar a OverrideMetadata(Type, PropertyMetadata), una clase derivada especifica su propio tipo como primer parámetro y una instancia de metadatos como el segundo parámetro.

Una clase derivada que invalide los metadatos de una propiedad de dependencia debe hacerlo antes de que el sistema de propiedades coloque la propiedad en uso. Una propiedad de dependencia se coloca en uso cuando se crea una instancia de la clase que registra la propiedad. Para ayudar a cumplir este requisito, la clase derivada debe llamar a OverrideMetadata dentro de su constructor estático. Al invalidar los metadatos de una propiedad de dependencia después de haber sido instanciado su tipo de propietario, no se generarán excepciones, pero se producirán comportamientos inconsistentes en el sistema de propiedades. Además, un tipo derivado no puede invalidar los metadatos de una propiedad de dependencia más de una vez e intentar hacerlo generará una excepción.

Ejemplo

En el ejemplo siguiente, la clase TropicalAquarium derivada invalida los metadatos de una propiedad de dependencia heredada de la clase Aquariumbase . El tipo de metadatos es FrameworkPropertyMetadata, que admite características del marco WPF relacionadas con la interfaz de usuario, como AffectsRender. La clase derivada no reemplaza la marca heredada AffectsRender, pero sí actualiza el valor predeterminado de AquariumGraphic en las instancias de la clase derivada.

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

Consulte también