Comment remplacer les métadonnées d’une propriété de dépendance (WPF .NET)

Lorsque vous dérivez d’une classe qui définit une propriété de dépendance, vous héritez de la propriété de dépendance et de ses métadonnées. Cet article explique comment remplacer les métadonnées d’une propriété de dépendance héritée en appelant la OverrideMetadata méthode. La substitution des métadonnées vous permet de modifier les caractéristiques de la propriété de dépendance héritée pour qu’elles correspondent aux exigences spécifiques aux sous-classes.

Important

La documentation du Guide du bureau pour .NET 7 et .NET 6 est en cours de construction.

Arrière-plan

Une classe qui définit une propriété de dépendance peut spécifier ses caractéristiques dans ou l’un PropertyMetadata de ses types dérivés, tels que FrameworkPropertyMetadata. L’une de ces caractéristiques est la valeur par défaut d’une propriété de dépendance. De nombreuses classes qui définissent les propriétés de dépendance, spécifient les métadonnées de propriété lors de l’inscription de propriétés de dépendance. Lorsque les métadonnées ne sont pas spécifiées lors de l’inscription, le système de propriétés WPF affecte un PropertyMetadata objet avec des valeurs par défaut. Les classes dérivées qui héritent des propriétés de dépendance par l’héritage de classe ont la possibilité de remplacer les métadonnées d’origine de toute propriété de dépendance. De cette façon, les classes dérivées peuvent modifier de manière sélective les caractéristiques de propriété de dépendance pour répondre aux exigences de classe. Lors de l’appel OverrideMetadata(Type, PropertyMetadata), une classe dérivée spécifie son propre type comme premier paramètre et une instance de métadonnées comme deuxième paramètre.

Une classe dérivée qui remplace les métadonnées d’une propriété de dépendance doit le faire avant que la propriété soit placée en cours d’utilisation par le système de propriétés. Une propriété de dépendance est placée en cours d’utilisation lorsqu’une instance de la classe qui inscrit la propriété est instanciée. Pour répondre à cette exigence, la classe dérivée doit appeler OverrideMetadata dans son constructeur statique. La substitution des métadonnées d’une propriété de dépendance après que son type de propriétaire n’est pas instanciée ne déclenche pas d’exceptions, mais entraîne des comportements incohérents dans le système de propriétés. En outre, un type dérivé ne peut pas remplacer les métadonnées d’une propriété de dépendance plusieurs fois et les tentatives de le faire déclenchent une exception.

Exemple

Dans l’exemple suivant, la classe TropicalAquarium dérivée remplace les métadonnées d’une propriété de dépendance héritée de la classe Aquariumde base. Le type de métadonnées est FrameworkPropertyMetadata, qui prend en charge les caractéristiques de l’infrastructure WPF liées à l’interface utilisateur telles que AffectsRender. La classe dérivée ne remplace pas l’indicateur hérité AffectsRender , mais met à jour la valeur par défaut des instances de AquariumGraphic classe dérivées.

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

Voir aussi