Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Die Windows Presentation Foundation (WPF)-Implementierung ihres XAML-Prozessors (Extensible Application Markup Language) ist von Natur aus auf Abhängigkeitseigenschaften ausgelegt. Daher verwendet der XAML-Prozessor WPF-Eigenschaftensystemmethoden, um XAML zu laden und Abhängigkeitseigenschaftenattribute zu verarbeiten. Dabei werden Abhängigkeitseigenschaften-Wrapper vollständig umgangen, indem WPF-Eigenschaftensystemmethoden wie GetValue und SetValue genutzt werden. Wenn Sie also dem Eigenschaftenwrapper Ihrer benutzerdefinierten Abhängigkeitseigenschaft benutzerdefinierte Logik hinzufügen, wird sie vom XAML-Prozessor nicht aufgerufen, wenn ein Eigenschaftswert in XAML festgelegt wird.
Voraussetzungen
In diesem Artikel wird davon ausgegangen, dass Sie über grundlegende Kenntnisse von Abhängigkeitseigenschaften verfügen und eine Übersicht über Abhängigkeitseigenschaften gelesen haben. Um den Beispielen in diesem Artikel zu folgen, hilft es Ihnen, wenn Sie mit Extensible Application Markup Language (XAML) vertraut sind und wissen, wie WPF-Anwendungen geschrieben werden.
Leistung des WPF-XAML-Ladeprogramms
Für den WPF-XAML-Prozessor ist es weniger rechenintensiv, den Wert einer Abhängigkeitseigenschaft direkt zu setzen und eine Funktion SetValue aufzurufen, anstatt den Eigenschaftenwrapper einer Abhängigkeitseigenschaft zu verwenden.
Wenn der XAML-Prozessor den Eigenschaftenwrapper verwenden würde, würde es erfordern, das gesamte Objektmodell des zugrunde liegenden Codes ausschließlich anhand der in der Markup angegebenen Typ- und Mitgliedsbeziehungen abzuleiten. Um den Typ anhand einer Kombination aus xmlns und Assembly-Attributen zu identifizieren, müssen die Member ermittelt, festgestellt werden, welche Member als Attribut festgelegt werden können, und die unterstützten Eigenschaftswerttypen aufgelöst werden, was eine umfangreiche Reflexion mit PropertyInfo erfordert.
Das WPF-Eigenschaftensystem verwaltet eine Speichertabelle mit Abhängigkeitseigenschaften, die für einen bestimmten DependencyObject abgeleiteten Typ implementiert wurden. Der XAML-Prozessor verwendet diese Tabelle, um den Abhängigkeitseigenschaftsbezeichner für eine Abhängigkeitseigenschaft abzuleiten. Der Bezeichner der Abhängigkeitseigenschaft für eine Abhängigkeitseigenschaft mit dem Namen ABC lautet ABCPropertystandardmäßig. Der XAML-Prozessor kann den Wert jeder Abhängigkeitseigenschaft effizient festlegen, indem er die SetValue Methode im zugehörigen Typ mithilfe des Abhängigkeitseigenschaftsbezeichners aufruft.
Weitere Informationen zu Wrappern von Abhängigkeitseigenschaften finden Sie unter Benutzerdefinierte Abhängigkeitseigenschaften.
Auswirkungen auf benutzerdefinierte Abhängigkeitseigenschaften
Der WPF-XAML-Prozessor umgeht Eigenschaftenwrapper und ruft direkt auf SetValue , um einen Abhängigkeitseigenschaftswert festzulegen. Vermeiden Sie daher, zusätzliche Logik in den set Accessor Ihrer benutzerdefinierten Abhängigkeitseigenschaft einzufügen, da diese Logik nicht ausgeführt wird, wenn ein Eigenschaftswert in XAML festgelegt wird. Der set Accessor sollte lediglich einen SetValue Aufruf enthalten.
Ebenso gibt es Aspekte des WPF-XAML-Prozessors, die beim Abrufen von Eigenschaftswerten den Eigenschaftswrapper umgehen und direkt GetValue aufrufen. Vermeiden Sie daher auch das Einfügen zusätzlicher Logik in den get Accessor Ihrer benutzerdefinierten Abhängigkeitseigenschaft, da diese Logik nicht ausgeführt wird, wenn ein Eigenschaftswert in XAML gelesen wird. Der get Accessor sollte lediglich einen GetValue Aufruf enthalten.
Dependency-Eigenschaft mit Wrapper-Beispiel
Das folgende Beispiel zeigt eine empfohlene Definition einer Abhängigkeitseigenschaft mit einem Eigenschaftenwrapper. Der Bezeichner der Abhängigkeitseigenschaft wird als public static readonly-Feld gespeichert. Die get- und set-Accessoren enthalten keinen Code außer den erforderlichen Methoden des WPF-Eigenschaftensystems, die dem Wert der Abhängigkeitseigenschaft zugrunde liegen. Wenn Sie Code haben, der ausgeführt werden muss, wenn sich der Wert Ihrer Abhängigkeitseigenschaft ändert, sollten Sie diesen Code in die PropertyChangedCallback Abhängigkeitseigenschaft einfügen. Weitere Informationen finden Sie unter Property-changed callbacks.
// Register a dependency property with the specified property name,
// property type, owner type, and property metadata. Store the dependency
// property identifier as a public static readonly member of the class.
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,
propertyChangedCallback: new PropertyChangedCallback(OnUriChanged))
);
// Property wrapper with get & set accessors.
public Uri AquariumGraphic
{
get => (Uri)GetValue(AquariumGraphicProperty);
set => SetValue(AquariumGraphicProperty, value);
}
// Property-changed callback.
private static void OnUriChanged(DependencyObject dependencyObject,
DependencyPropertyChangedEventArgs e)
{
// Some custom logic that runs on effective property value change.
Uri newValue = (Uri)dependencyObject.GetValue(AquariumGraphicProperty);
Debug.WriteLine($"OnUriChanged: {newValue}");
}
' Register a dependency property with the specified property name,
' property type, owner type, and property metadata. Store the dependency
' property identifier as a public static readonly member of the class.
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,
propertyChangedCallback:=New PropertyChangedCallback(AddressOf OnUriChanged)))
' Property 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
' Property-changed callback.
Private Shared Sub OnUriChanged(dependencyObject As DependencyObject,
e As DependencyPropertyChangedEventArgs)
' Some custom logic that runs on effective property value change.
Dim newValue As Uri = CType(dependencyObject.GetValue(AquariumGraphicProperty), Uri)
Debug.WriteLine($"OnUriChanged: {newValue}")
End Sub
Siehe auch
.NET Desktop feedback