Caricamento XAML e proprietà di dipendenza

L'implementazione WPF corrente del processore XAML è intrinsecamente compatibile con la proprietà di dipendenza. Il processore XAML WPF usa metodi di sistema delle proprietà per le proprietà di dipendenza durante il caricamento di attributi XAML binari ed elaborazione che sono proprietà di dipendenza. Ciò consente di ignorare in modo efficace i wrapper della proprietà. Quando si implementano proprietà di dipendenza personalizzate, è necessario tenere conto di questo comportamento ed evitare di inserire qualsiasi altro codice nel wrapper della proprietà diverso dai metodi GetValue di sistema delle proprietà e SetValue.

Prerequisiti

Questo argomento presuppone la conoscenza delle proprietà di dipendenza sia in qualità di consumer, sia in qualità di autore oltre alla lettura di Cenni preliminari sulle proprietà di dipendenza e Proprietà Dependency personalizzate. Dovresti anche avere letto XAML in WPF e sintassi XAML in dettaglio.

Implementazione del caricatore XAML WPF e prestazioni

Per motivi di implementazione, è meno costoso identificare una proprietà come proprietà di dipendenza e accedere al metodo del sistema SetValue di proprietà per impostarlo, anziché usare il wrapper della proprietà e il relativo setter. Ciò è dovuto al fatto che un processore XAML deve dedurre l'intero modello a oggetti del codice di supporto in base solo alla conoscenza delle relazioni tra tipo e membro indicate dalla struttura del markup e dalle varie stringhe.

Il tipo viene cercato tramite una combinazione di attributi xmlns e assembly, ma identificando i membri, determinando quale potrebbe supportare l'impostazione come attributo e risolvendo i tipi supportati dai valori delle proprietà altrimenti richiederebbe una reflection estesa usando PropertyInfo. Poiché le proprietà di dipendenza in un determinato tipo sono accessibili come tabella di archiviazione tramite il sistema di proprietà, l'implementazione WPF del processore XAML usa questa tabella e deduce che qualsiasi proprietà SPECIFICA ABC può essere impostata in modo più efficiente chiamando SetValue sul tipo derivato contenitore DependencyObject , usando l'identificatore della proprietà di dipendenza ABCProperty.

Implicazioni per le proprietà di dipendenza personalizzate

Poiché l'implementazione WPF corrente del comportamento del processore XAML per l'impostazione della proprietà ignora completamente i wrapper, non devi inserire alcuna logica aggiuntiva nelle definizioni del set del wrapper per la proprietà di dipendenza personalizzata. Se si inserisce tale logica nella definizione del set, la logica non verrà eseguita quando la proprietà viene impostata in XAML anziché nel codice.

Analogamente, altri aspetti del processore XAML che ottengono i valori delle proprietà dall'elaborazione XAML usano GetValue anche anziché usare il wrapper. Pertanto, è anche consigliabile evitare qualsiasi implementazione aggiuntiva nella get definizione oltre la GetValue chiamata.

L'esempio seguente è una definizione di una proprietà di dipendenza consigliata con wrapper, in cui l'identificatore di proprietà è archiviato come campo publicstaticreadonly e le definizioni get e set non contengono codice oltre ai metodi del sistema di proprietà necessari che definiscono il supporto della proprietà di dipendenza.


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

Vedi anche