Carga de XAML y propiedades de dependencia

Tener en cuenta las propiedades de dependencia es inherente a la implementación actual en WPF del procesador XAML. El procesador XAML de WPF utiliza métodos del sistema de propiedades para las propiedades de dependencia al cargar el XAML binario y al procesar atributos que son propiedades de dependencia. En la práctica esto supone la omisión de los contenedores de propiedad. Al implementar propiedades de dependencia personalizadas, debe tener en cuenta este comportamiento y evitar incluir en el contenedor de propiedad ningún código que no sean los métodos del sistema de propiedades GetValue y SetValue.

Este tema contiene las secciones siguientes.

  • Requisitos previos
  • Implementación de cargador de XAML de WPF y rendimiento
  • Implicaciones para las propiedades de dependencia personalizadas
  • Temas relacionados

Requisitos previos

En este tema se supone que el lector comprende las propiedades de dependencia como consumidor y como autor, y que ha leído los artículos Información general sobre las propiedades de dependencia y Propiedades de dependencia personalizadas. También es conveniente haber leído Información general sobre XAML (WPF) y Detalles de la sintaxis XAML.

Implementación de cargador de XAML de WPF y rendimiento

Por motivos de implementación, resulta menos costoso desde el punto de vista de la informática identificar una propiedad como de dependencia y tener acceso al método SetValue del sistema de propiedades para establecerla, en lugar de utilizar el contenedor de propiedad y su establecedor. Esto se debe a que un procesador XAML debe deducir el modelo de objetos completo del código de respaldo basándose únicamente en las relaciones entre los miembros y los tipos que se indican en la estructura del marcado y en diversas cadenas.

El tipo se busca mediante una combinación de xmlns y atributos de ensamblado, pero para identificar los miembros, determinar cuáles admiten que se los establezca como atributos, y resolver qué tipos admiten las propiedades, se requeriría llevar a cabo una extensa reflexión mediante PropertyInfo. Dado que las propiedades de dependencia de un tipo determinado están accesibles como una tabla de almacenamiento a través del sistema de propiedades, la implementación en WPF del procesador XAML utiliza esta tabla y deduce que cualquier propiedad ABC determinada se puede establecer de un modo más eficaz llamando al método SetValue del tipo derivado contenedor DependencyObject, para lo que se utiliza el identificador de propiedad de dependencia ABCPropiedad.

Implicaciones para las propiedades de dependencia personalizadas

Dado que la implementación actual en WPF del comportamiento del procesador XAML para establecer propiedades omite completamente los contenedores, no se debe incluir ninguna lógica adicional en las definiciones de conjuntos del contenedor para la propiedad de dependencia personalizada. Si incluye lógica de este tipo en la definición de conjuntos, dicha lógica no se ejecutará cuando la propiedad se establezca en XAML en lugar de mediante código.

De igual forma, otros aspectos del procesador XAML que obtienen valores de propiedades del procesamiento XAML también utilizan GetValue en lugar del contenedor. Por consiguiente, también se debe evitar cualquier implementación adicional en la definición de get que no sea la llamada a GetValue.

El ejemplo siguiente es una definición de propiedad de dependencia recomendada con contenedores, donde el identificador de propiedad está almacenado como un campo publicstaticreadonly y las definiciones de set y get no contienen ningún código excepto los métodos del sistema de propiedades necesarios que definen la lógica de respaldo de las propiedades de dependencia.


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

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); }
}

Vea también

Conceptos

Información general sobre las propiedades de dependencia

Información general sobre XAML (WPF)

Metadatos de las propiedades de dependencia

Propiedades de dependencia de tipo de colección

Seguridad de las propiedades de dependencia

Modelos de constructores seguros para objetos DependencyObject