Schreibgeschützte Abhängigkeitseigenschaften (WPF .NET)

Sie können schreibgeschützte Abhängigkeitseigenschaften verwenden, um zu verhindern, dass Eigenschaftswerte von außerhalb des Codes festgelegt werden. In diesem Artikel werden vorhandene schreibgeschützte Abhängigkeitseigenschaften und die Szenarien und Techniken zum Erstellen einer benutzerdefinierten schreibgeschützten Abhängigkeitseigenschaft erläutert.

Wichtig

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

Voraussetzungen

Im Artikel wird davon ausgegangen, dass sie grundlegende Kenntnisse über Abhängigkeitseigenschaften haben und eine Übersicht über Abhängigkeitseigenschaften gelesen haben. Für die Beispiele in diesem Artikel ist es hilfreich, wenn Sie mit Extensible Application Markup Language (XAML) vertraut sind und wissen, wie WPF-Anwendungen geschrieben werden.

Vorhandener schreibgeschützte Abhängigkeitseigenschaften

Schreibgeschützte Abhängigkeitseigenschaften melden in der Regel den Zustand und sollten nicht über eine public-Zugriffsmethode geändert werden. Das WPF-Framework (Windows Presentation Foundation) implementiert beispielsweise die IsMouseOver-Eigenschaft als schreibgeschützt, da der Wert nur durch Mauseingaben bestimmt werden soll. Wenn IsMouseOver andere Eingaben zulässt, kann es passieren, dass der Wert mit der Mauseingabe inkonsistent wird. Auch wenn sie nicht über eine public-Zugriffsmethode festgelegt werden können, verfügen viele vorhandene schreibgeschützte Abhängigkeitseigenschaften dennoch über Werte, die durch mehrere Eingaben bestimmt werden.

Verwenden vorhandener schreibgeschützter Abhängigkeitseigenschaften

Schreibgeschützte Abhängigkeitseigenschaften sind für mehrere Szenarien, in denen Abhängigkeitseigenschaften normalerweise eine Lösung darstellen, nicht geeignet. Zu den nicht geeigneten Szenarien zählen Datenbindung, Anwendung einer Formatvorlage auf einen Wert, Validierung, Animation und Vererbung. Eine schreibgeschützte Abhängigkeitseigenschaft kann jedoch als Eigenschaftsauslöser in einer Formatvorlage verwendet werden. IsMouseOver wird beispielsweise häufig verwendet, um Änderungen am Hintergrund, am Vordergrund oder an einer anderen sichtbaren Eigenschaft eines Steuerelements auszulösen, wenn der Mauszeiger darauf bewegt wird. Das WPF-Eigenschaftensystem erkennt und meldet Änderungen in schreibgeschützten Abhängigkeitseigenschaften und unterstützt so die Funktion von Eigenschaftstriggern. Schreibgeschützte Abhängigkeitseigenschaften sind auch hilfreich, wenn eine Abhängigkeitseigenschaft vom Typ „Auflistung“ implementiert wird, bei der nur die Auflistungselemente schreibbar sein müssen, aber nicht das Auflistungsobjekt selbst. Weitere Informationen finden Sie unter Abhängigkeitseigenschaften des Sammlungstyps (WPF .NET).

Hinweis

Als Eigenschaftsauslöser in einer Formatvorlage können nur Abhängigkeitseigenschaften verwendet werden. Reguläre CLR-Eigenschaften (Common Language Runtime) können hierfür nicht verwendet werden.

Erstellen benutzerdefinierter schreibgeschützter Abhängigkeitseigenschaften

Überprüfen Sie vor dem Erstellen einer schreibgeschützten Abhängigkeitseigenschaft die nicht geeigneten Szenarien.

Der Prozess zum Erstellen einer schreibgeschützten Abhängigkeitseigenschaft ist in vielerlei Hinsicht mit der Erstellung von Abhängigkeitseigenschaften mit Lese- und Schreibzugriff vergleichbar. Es gibt jedoch folgende Unterschiede:

  • Rufen Sie beim Registrieren Ihrer schreibgeschützten Eigenschaft RegisterReadOnly anstelle von Register auf.

  • Achten Sie beim Implementieren des CLR-Eigenschaftswrappers darauf, dass er keine öffentliche set-Zugriffsmethode hat.

  • RegisterReadOnly gibt DependencyPropertyKey anstelle von DependencyProperty zurück. Speichern Sie den Schlüssel der Abhängigkeitseigenschaft (DependencyPropertyKey) in einem nicht öffentlichen Klassenmitglied.

Sie können den Wert Ihrer schreibgeschützten Abhängigkeitseigenschaft mithilfe einer Logik Ihrer Wahl ermitteln. Empfohlen wird, als Methode zum Festlegen des Eigenschaftswerts (entweder zu Beginn oder im Rahmen der Laufzeitlogik) die Überladung von SetValue zu verwenden, die einen Parameter vom Typ DependencyPropertyKey akzeptiert. Die Verwendung von SetValue ist der Umgehung des Eigenschaftensystems und der direkten Festlegung des Unterstützungsfelds vorzuziehen.

Wie und wo Sie den Wert einer schreibgeschützten Abhängigkeitseigenschaft innerhalb Ihrer Anwendung festlegen, hat Auswirkungen auf die Zugriffsebene, die Sie dem Klassenmitglied zuweisen, das den Schlüssel der Abhängigkeitseigenschaft (DependencyPropertyKey) speichert. Wenn Sie den Eigenschaftswert nur innerhalb der Klasse festlegen, die die Abhängigkeitseigenschaft registriert, können Sie einen Zugriffsmodifizierer vom Typ private verwenden. In Szenarien, in denen sich die Werte von Abhängigkeitseigenschaften aufeinander auswirken, können Sie gekoppelte PropertyChangedCallback- und CoerceValueCallback-Rückrufe verwenden, um Wertänderungen auszulösen. Weitere Informationen finden Sie unter Metadaten für Abhängigkeitseigenschaften (WPF .NET).

Wenn Sie den Wert einer schreibgeschützten Abhängigkeitseigenschaft von außerhalb der Klasse ändern müssen, die sie registriert, können Sie einen Zugriffsmodifizierer vom Typ internal für den Schlüssel der Abhängigkeitseigenschaft (DependencyPropertyKey) verwenden. So können Sie beispielsweise SetValue über einen Ereignishandler in der gleichen Assembly aufrufen. Im folgenden Beispiel wird eine Aquarium-Klasse definiert, die RegisterReadOnly aufruft, um die schreibgeschützte Abhängigkeitseigenschaft FishCountzu erstellen. Der Schlüssel der Abhängigkeitseigenschaft (DependencyPropertyKey) wird einem Feld vom Typ internal static readonly zugewiesen, sodass Code in der gleichen Assembly den Wert der schreibgeschützten Abhängigkeitseigenschaft ändern kann.

public class Aquarium : DependencyObject
{
    // Register a dependency property with the specified property name,
    // property type, owner type, and property metadata.
    // Assign DependencyPropertyKey to a nonpublic field.
    internal static readonly DependencyPropertyKey FishCountPropertyKey =
        DependencyProperty.RegisterReadOnly(
          name: "FishCount",
          propertyType: typeof(int),
          ownerType: typeof(Aquarium),
          typeMetadata: new FrameworkPropertyMetadata());

    // Declare a public get accessor.
    public int FishCount =>
        (int)GetValue(FishCountPropertyKey.DependencyProperty);
}
Public Class Aquarium
    Inherits DependencyObject

    ' Register a dependency property with the specified property name,
    ' property type, owner type, And property metadata.
    ' Assign DependencyPropertyKey to a nonpublic field.
    Friend Shared ReadOnly FishCountPropertyKey As DependencyPropertyKey =
        DependencyProperty.RegisterReadOnly(
            name:="FishCount",
            propertyType:=GetType(Integer),
            ownerType:=GetType(Aquarium),
            typeMetadata:=New FrameworkPropertyMetadata())

    ' Declare a public get accessor.
    Public ReadOnly Property FishCount As Integer
        Get
            Return GetValue(FishCountPropertyKey.DependencyProperty)
        End Get
    End Property

End Class

Da das WPF-Eigenschaftensystem den Schlüssel der Abhängigkeitseigenschaft (DependencyPropertyKey) nicht außerhalb des externen Codes verteilt, bieten schreibgeschützte Abhängigkeitseigenschaften eine höhere Schreibsicherheit als Abhängigkeitseigenschaften mit Lese- und Schreibzugriff. Verwenden Sie eine schreibgeschützte Abhängigkeitseigenschaft, wenn Sie den Schreibzugriff auf diejenigen beschränken möchten, die über einen Verweis auf den Schlüssel der Abhängigkeitseigenschaft (DependencyPropertyKey) verfügen.

Im Gegensatz dazu ist der Bezeichner der Abhängigkeitseigenschaft für Abhängigkeitseigenschaften mit Lese- und Schreibzugriff über das Eigenschaftensystem zugänglich – unabhängig davon, welche Zugriffsmodifizierer Sie ihm zuweisen. Weitere Informationen finden Sie unter Sicherheit von Abhängigkeitseigenschaften (WPF .NET).

Weitere Informationen