Jak zastąpić metadane właściwości zależności (WPF .NET)

Gdy pochodzisz z klasy, która definiuje właściwość zależności, dziedziczysz właściwość zależności i jej metadane. W tym artykule opisano sposób zastępowania metadanych dziedziczonej właściwości zależności przez wywołanie OverrideMetadata metody . Zastąpienie metadanych umożliwia modyfikowanie właściwości dziedziczonej zależności w celu dopasowania ich do wymagań specyficznych dla podklasy.

Ważne

Dokumentacja przewodnika dla komputerów dla platform .NET 7 i .NET 6 jest w budowie.

Tło

Klasa, która definiuje właściwość zależności, może określać jego cechy w PropertyMetadata lub jeden z jego typów pochodnych, takich jak FrameworkPropertyMetadata. Jedną z tych cech jest domyślna wartość właściwości zależności. Wiele klas, które definiują właściwości zależności, określa metadane właściwości podczas rejestracji właściwości zależności. Jeśli metadane nie są określone podczas rejestracji, system właściwości WPF przypisuje PropertyMetadata obiekt z wartościami domyślnymi. Klasy pochodne dziedziczące właściwości zależności za pośrednictwem dziedziczenia klas mają możliwość zastąpienia oryginalnych metadanych dowolnej właściwości zależności. W ten sposób klasy pochodne mogą selektywnie modyfikować cechy właściwości zależności w celu spełnienia wymagań klasy. Podczas wywoływania OverrideMetadata(Type, PropertyMetadata)klasy pochodnej określa swój własny typ jako pierwszy parametr, a wystąpienie metadanych jako drugi parametr.

Klasa pochodna, która zastępuje metadane właściwości zależności, musi to zrobić, zanim właściwość zostanie umieszczona w użyciu przez system właściwości. Właściwość zależności jest umieszczana w użyciu, gdy wystąpią wystąpienia dowolnej klasy, która rejestruje właściwość. Aby spełnić to wymaganie, klasa pochodna powinna wywołać OverrideMetadata element w jego konstruktorze statycznym. Zastąpienie metadanych właściwości zależności po utworzeniu wystąpienia typu właściciela nie spowoduje wystąpienia wyjątków, ale spowoduje niespójne zachowania w systemie właściwości. Ponadto typ pochodny nie może zastąpić metadanych właściwości zależności więcej niż raz, a próby wykonania tej czynności spowodują wystąpienie wyjątku.

Przykład

W poniższym przykładzie klasa TropicalAquarium pochodna zastępuje metadane właściwości zależności dziedziczonej z klasy Aquariumbazowej . Typ metadanych to FrameworkPropertyMetadata, który obsługuje cechy struktury WPF związane z interfejsem użytkownika, takie jak AffectsRender. Klasa pochodna nie zastępuje odziedziczonej AffectsRender flagi, ale aktualizuje wartość AquariumGraphic domyślną dla wystąpień klasy pochodnej.

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

Zobacz też