Поделиться через


Переопределение метаданных для свойства зависимости (WPF .NET)

При наследовании от класса, определяющего свойство зависимостей, наследуется свойство зависимостей и его метаданные. В этой статье описывается, как переопределить метаданные унаследованного свойства зависимостей, вызвав метод OverrideMetadata. Переопределение метаданных позволяет изменять характеристики унаследованного свойства зависимостей в соответствии с требованиями к подклассам.

Фон

Класс, определяющий свойство зависимостей, может указать характеристики в PropertyMetadata или один из производных типов, например FrameworkPropertyMetadata. Одним из этих характеристик является значение по умолчанию свойства зависимостей. Многие классы, определяющие свойства зависимостей, указывают метаданные свойств во время регистрации свойств зависимостей. Если метаданные не указаны во время регистрации, система свойств WPF назначает объект PropertyMetadata со значениями по умолчанию. Производные классы, наследующие свойства зависимостей через наследование классов, имеют возможность переопределить исходные метаданные любого свойства зависимостей. Таким образом производные классы могут выборочно изменять характеристики свойств зависимостей в соответствии с требованиями класса. При вызове OverrideMetadata(Type, PropertyMetadata)производный класс задает собственный тип в качестве первого параметра и экземпляр метаданных в качестве второго параметра.

Производный класс, который переопределяет метаданные для свойства зависимостей, должен сделать это, прежде чем свойство будет использоваться системой свойств. Свойство зависимости используется, когда создается экземпляр любого класса, который его регистрирует. Чтобы обеспечить соответствие этому требованию, производный класс должен вызывать OverrideMetadata в статическом конструкторе. Переопределение метаданных свойства зависимости после создания экземпляра типа владельца не вызывает исключений, но приведет к несогласованному поведению системы свойств. Кроме того, производный тип не может переопределить метаданные свойства зависимостей несколько раз, и попытки сделать это приведет к возникновению исключения.

Пример

В следующем примере производный класс TropicalAquarium переопределяет метаданные свойства зависимостей, унаследованного от базового класса Aquarium. Тип метаданных — FrameworkPropertyMetadata, который поддерживает характеристики платформы WPF, связанные с пользовательским интерфейсом, например AffectsRender. Производный класс не переопределяет наследуемый флаг AffectsRender, но обновляет значение по умолчанию AquariumGraphic для экземпляров производных классов.

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

См. также