Laden von XAML und Abhängigkeitseigenschaften

Die aktuelle WPF-Implementierung des XAML-Prozessors berücksichtigt Abhängigkeitseigenschaften. Der WPF-XAML-Prozessor verwendet Methoden des Eigenschaftensystems zum Laden von binärem XAML-Code und zum Verarbeiten von Attributen, die Abhängigkeitseigenschaften sind. Dadurch werden Eigenschaftenwrapper praktisch umgangen. Wenn Sie benutzerdefinierte Abhängigkeitseigenschaften implementieren, müssen Sie dieses Verhalten berücksichtigen und vermeiden, in Ihrem Eigenschaftenwrapper außer den Methoden GetValue und SetValue des Eigenschaftensystems weiteren Code zu verwenden.

Voraussetzungen

In diesem Thema wird davon ausgegangen, dass Sie Abhängigkeitseigenschaften sowohl aus Sicht eines Anwenders als auch der eines Autors verstehen, und dass Sie Übersicht über Abhängigkeitseigenschaften und Benutzerdefinierte Abhängigkeitseigenschaften gelesen haben. Sie sollten auch die Informationen unter XAML in WPF und Ausführliche Erläuterung der XAML-Syntax gelesen haben.

Implementierung und Leistung des WPF-XAML-Ladeprogramms

Was die Implementierung betrifft, ist es weniger rechenintensiv, eine Eigenschaft als Abhängigkeitseigenschaft zu identifizieren und sie mittels Aufruf der Methode SetValue des Eigenschaftensystem festzulegen, als den Eigenschaftenwrapper und dessen Setter zu verwenden. Grund hierfür ist, dass der XAML-Prozessor das gesamte Objektmodell des unterstützenden Codes allein auf Basis der Typ- und Mitgliedsbeziehungen, die durch die Markupstruktur und verschiedene Zeichenfolgen erkennbar sind, herleiten muss.

Der Typ kann durch eine Kombination von xmlns- und Assemblyattributen hergeleitet werden. Die Identifizierung der Mitglieder hingegen würde sonst umfangreiche Reflektion mithilfe von PropertyInfo erfordern, wenn ermittelt werden soll, welches möglicherweise als Attribut festgelegt werden darf, und aufgelöst werden soll, welche Typen die Eigenschaftswerte unterstützen. Da Abhängigkeitseigenschaften für einen bestimmten Typ über das Eigenschaftensystem als Speichertabelle abrufbar sind, nutzt die WPF-Implementierung des XAML-Prozessors diese Tabelle und folgert, dass über den Bezeichner ABCProperty der Abhängigkeitseigenschaft eine jede Eigenschaft ABC effizienter festgelegt werden kann, indem SetValue für den enthaltenden abgeleiteten Typ DependencyObject aufgerufen wird.

Auswirkungen auf Benutzerdefinierte Abhängigkeitseigenschaften

Da die aktuelle WPF-Implementierung des XAML-Prozessorverhaltens für die Festlegung von Eigenschaften die Wrapper vollständig umgeht, dürfen Sie keine zusätzliche Logik in die Set-Definitionen des Wrappers für die benutzerdefinierte Abhängigkeitseigenschaft einfügen. Wenn Sie solche Logik in der Set-Definition einfügen, wird diese Logik nicht ausgeführt werden, wenn die Eigenschaft in XAML statt in Code festgelegt wird.

Gleiches gilt für andere Aspekte des XAML-Prozessors, die Eigenschaftswerte aus der XAML-Verarbeitung mittels GetValue abrufen, statt den Wrapper zu verwenden. Sie sollten daher ebenfalls jede Art von zusätzlicher Implementierung in der get-Definition vermeiden, die über den Aufruf von GetValue hinausgeht.

Das folgende Beispiel ist eine empfohlene Definition von Abhängigkeitseigenschaften mit Wrappern, wobei der Eigenschaftenbezeichner als Feld vom Typ public static readonly gespeichert wird und die get- und set-Definitionen keinen Code außer den erforderlichen Methoden des Eigenschaftensystems enthalten, die die Unterstützung der Abhängigkeitseigenschaft definieren.


public static readonly DependencyProperty AquariumGraphicProperty = DependencyProperty.Register(
  "AquariumGraphic",
  typeof(Uri),
  typeof(AquariumObject),
  new FrameworkPropertyMetadata(null,
      FrameworkPropertyMetadataOptions.AffectsRender,
      new PropertyChangedCallback(OnUriChanged)
  )
);
public Uri AquariumGraphic
{
  get { return (Uri)GetValue(AquariumGraphicProperty); }
  set { SetValue(AquariumGraphicProperty, value); }
}

Public Shared ReadOnly AquariumGraphicProperty As DependencyProperty = DependencyProperty.Register("AquariumGraphic", GetType(Uri), GetType(AquariumObject), New FrameworkPropertyMetadata(Nothing, FrameworkPropertyMetadataOptions.AffectsRender, New PropertyChangedCallback(AddressOf OnUriChanged)))
Public Property AquariumGraphic() As Uri
    Get
        Return CType(GetValue(AquariumGraphicProperty), Uri)
    End Get
    Set(ByVal value As Uri)
        SetValue(AquariumGraphicProperty, value)
    End Set
End Property

Weitere Informationen