Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
La implementación de Windows Presentation Foundation (WPF) de su procesador de lenguaje de marcado para aplicaciones extensibles (XAML) está intrínsecamente consciente de las propiedades de dependencia. Por lo tanto, el procesador XAML utiliza métodos del sistema de propiedades de WPF para cargar XAML y procesar atributos de propiedad de dependencia, y omite completamente los contenedores de propiedades de dependencia mediante métodos del sistema de propiedades de WPF como GetValue y SetValue. Por lo tanto, si agregas lógica personalizada al contenedor de propiedades de la propiedad de dependencia personalizada, el procesador XAML no lo llamará cuando se establezca un valor de propiedad en XAML.
Prerrequisitos
El artículo asume que tiene un conocimiento básico de las propiedades de dependencia y que ha leído Descripción general de las propiedades de dependencia. Para seguir los ejemplos de este artículo, le ayuda si está familiarizado con el lenguaje de marcado extensible de aplicaciones (XAML) y sabe cómo escribir aplicaciones WPF.
Rendimiento del cargador XAML de WPF
Es computacionalmente menos costoso que el procesador XAML de WPF llame directamente a SetValue para establecer el valor de una propiedad de dependencia, en lugar de usar el contenedor de una propiedad de dependencia.
Si el procesador XAML usaba el contenedor de propiedades, requeriría deducir todo el modelo de objetos del código de respaldo basado solo en las relaciones de tipo y miembro indicadas en el marcado. Aunque el tipo se puede identificar a partir del marcado mediante una combinación de xmlns
y atributos de ensamblado, identificar los miembros, determinar qué miembros se pueden establecer como un atributo y resolver los tipos de valor de propiedad admitidos requeriría una reflexión extensa utilizando PropertyInfo.
El sistema de propiedades de WPF mantiene una tabla de almacenamiento de propiedades de dependencia implementadas en un tipo derivado determinado DependencyObject . El procesador XAML utiliza esa tabla para inferir el identificador de la propiedad de dependencia. Por ejemplo, por convención, el identificador de propiedad de dependencia de una propiedad de dependencia denominada ABC
es ABCProperty
. El procesador XAML puede establecer eficazmente el valor de cualquier propiedad de dependencia llamando al SetValue
método en su tipo contenedor mediante el identificador de propiedad de dependencia.
Para obtener más información sobre los contenedores de propiedades de dependencia, consulte Propiedades de dependencia personalizadas.
Implicaciones para las propiedades de dependencia personalizadas
El procesador XAML de WPF omite los envoltorios de propiedades y llama directamente a SetValue para establecer un valor de propiedad dependiente. Por lo tanto, evite colocar cualquier lógica adicional en el set
accesor de la propiedad de dependencia personalizada, dado que no se ejecutará cuando se establezca un valor de propiedad en XAML. El set
accesor solo debe contener una llamada a SetValue
.
Del mismo modo, los aspectos del procesador XAML de WPF que obtienen valores de propiedad omiten el contenedor de propiedades y llaman directamente a GetValue. Por lo tanto, también evite colocar cualquier lógica adicional en el get
descriptor de acceso de su propiedad de dependencia personalizada porque esa lógica no se ejecutará cuando se lea un valor de propiedad en XAML. El get
accesor solo debe contener una llamada a GetValue
.
Ejemplo de propiedad de dependencia con envoltorio
En el ejemplo siguiente se muestra una definición recomendada de propiedad de dependencia con envoltorios de propiedades. El identificador de propiedad de dependencia se almacena como un public static readonly
campo y los get
descriptores de acceso y set
no contienen ningún código más allá de los métodos necesarios del sistema de propiedades de WPF que respaldan el valor de la propiedad de dependencia. Si tiene código que debe ejecutarse cuando cambie el valor de la propiedad de dependencia, considere colocar ese código en el PropertyChangedCallback de su propiedad de dependencia. Para obtener más información, consulte callbacks de cambio de propiedad.
// 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
Consulte también
.NET Desktop feedback