XAML 載入和相依性屬性

XAML 處理器目前的 WPF 實作,在本質上就會感知相依性屬性。 WPF XAML 處理器在載入二進位 XAML 和處理相依性屬性的屬性時,會使用相依性屬性的屬性系統方法。 這可有效略過屬性的包裝函式。 在實作自訂相依性屬性時,您必須注意這項行為,並避免在屬性包裝函式中放置任何其他程式碼,而只能放置 GetValueSetValue 屬性系統方法。

必要條件

本主題假設您已從相依性屬性的消費者和作者角度了解相依性屬性,並已閱讀相依性屬性概觀自訂相依性屬性。 此外,您應已閱讀 WPF 中的 XAMLXAML 語法詳細資料

WPF XAML 載入器實作與效能

基於實作原因,若您將屬性識別為相依性屬性,並藉由存取屬性系統 SetValue 方法來進行設定,而不使用屬性包裝函式和其 setter,會比較節省運算成本。 這是因為 XAML 處理器僅能藉由各種字串和標記之結構所表示的型別和成員關聯性,來推斷支援程式碼的整個物件模型。

系統可以透過 xmlns 和組件屬性的組合來查閱型別,但若要識別成員、判斷哪些項目可以支援設為屬性,並解析出支援何種型別和屬性值,就需要使用 PropertyInfo 以進行廣泛的反映作業。 由於指定型別的相依性屬性可透過屬性系統的儲存體資料表進行存取,因此 XAML 處理器的 WPF 實作會使用此資料表推斷出下列項目:比起使用相依性屬性識別項 ABCProperty,在所含的 DependencyObject 衍生型別上呼叫 SetValue,應可更有效率設定任何給定屬性 ABC

自訂相依性屬性的影響

由於目前 XAML 處理器的 WPF 實作其屬性設定行為完全略過包裝函式,因此您不應該將任何其他邏輯放入自訂相依性屬性之包裝函式的集合定義中。 如果您在集合定義中放置這類邏輯,則在 XAML 中設定屬性 (而不是在程式碼中設定) 時,將不會執行邏輯。

同樣地,如果 XAML 處理器的其他項目是藉由處理 XAML 來取得屬性值,則也會使用 GetValue 而不使用包裝函式。 因此,您也應該避免在 get 定義中進行超過 GetValue 呼叫範圍的任何其他實作。

下列範例是建議的相依性屬性定義與包裝函式,其中將屬性識別項儲存為 publicstaticreadonly 欄位,而 getset 定義所包含的程式碼也都在定義支援相依性屬性的必要屬性系統方法範圍內。


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

另請參閱