Überschreiben von Metadaten für eine Abhängigkeitseigenschaft (WPF .NET)

Wenn Sie von einer Klasse ableiten, die eine Abhängigkeitseigenschaft definiert, erben Sie die Abhängigkeitseigenschaft und die zugehörigen Metadaten. Dieser Artikel beschreibt, wie Sie die Metadaten einer geerbten Abhängigkeitseigenschaft überschreiben können, indem Sie die Methode OverrideMetadata aufrufen. Durch das Überschreiben der Metadaten können Sie die Eigenschaften der geerbten Abhängigkeitseigenschaft so ändern, dass sie den spezifischen Anforderungen der Unterklassen entspricht.

Wichtig

Der Desktopleitfaden zu .NET 7 und .NET 6 ist in Bearbeitung.

Hintergrund

Eine Klasse, die eine Abhängigkeitseigenschaft definiert, kann ihre Merkmale in PropertyMetadata oder einem ihrer abgeleiteten Typen (z. B. FrameworkPropertyMetadata) angeben. Eines dieser Merkmale ist der Standardwert einer Abhängigkeitseigenschaft. Viele Klassen, die Abhängigkeitseigenschaften definieren, geben bei der Registrierung von Abhängigkeitseigenschaften Eigenschaftenmetadaten an. Wenn während der Registrierung keine Metadaten angegeben werden, weist das WPF-Eigenschaftensystem ein PropertyMetadata-Objekt mit Standardwerten zu. Abgeleitete Klassen, die per Klassenvererbung Abhängigkeitseigenschaften erben, können die ursprünglichen Metadaten jeder Abhängigkeitseigenschaft außer Kraft setzen. Auf diese Weise können abgeleitete Klassen die Eigenschaften von Abhängigkeitseigenschaften selektiv ändern, um die Anforderungen der Klasse zu erfüllen. Beim Aufruf von OverrideMetadata(Type, PropertyMetadata) gibt eine abgeleitete Klasse ihren eigenen Typ als ersten Parameter und eine Metadateninstanz als zweiten Parameter an.

Eine abgeleitete Klasse, die die Metadaten einer Abhängigkeitseigenschaft außer Kraft setzt, muss dies tun, bevor die Eigenschaft vom Eigenschaftensystem in Gebrauch genommen wird. Eine Abhängigkeitseigenschaft wird in Gebrauch genommen, wenn eine Instanz der Klasse, die die Eigenschaft registriert, instanziiert wird. Um diese Anforderung zu erfüllen, sollte die abgeleitete Klasse OverrideMetadata in ihrem statischen Konstruktor aufrufen. Das Überschreiben der Metadaten einer Abhängigkeitseigenschaft nach der Instanziierung des Besitzertyps löst keine Ausnahmen aus, führt aber zu einem inkonsistenten Verhalten im Eigenschaftensystem. Außerdem kann ein abgeleiteter Typ die Metadaten einer Abhängigkeitseigenschaft nicht mehrmals überschreiben, und ein solcher Versuch löst eine Ausnahme aus.

Beispiel

Im folgenden Beispiel überschreibt die abgeleitete Klasse TropicalAquarium die Metadaten einer von der Basisklasse Aquarium geerbten Abhängigkeitseigenschaft. Der Metadatentyp lautet FrameworkPropertyMetadata, der UI-bezogene Merkmale des WPF-Frameworks wie z. B. AffectsRender unterstützt. Die abgeleitete Klasse setzt das geerbte AffectsRender-Flag nicht außer Kraft, aber sie aktualisiert den Standardwert von AquariumGraphic für Instanzen der abgeleiteten Klasse.

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

Weitere Informationen