Información general sobre propiedades asociadas

Una propiedad asociada es un concepto definido por Extensible Application Markup Language (XAML). Las propiedades asociadas están destinadas a utilizarse como un tipo de propiedad global configurable en cualquier objeto. En Windows Presentation Foundation (WPF), las propiedades asociadas se definen habitualmente como una forma especializada de propiedad de dependencia que no tiene el "contenedor" de propiedad convencional.

Este tema contiene las secciones siguientes.

  • Requisitos previos
  • Por qué usar propiedades asociadas
  • Propiedades asociadas en XAML
  • Cómo el tipo propietario utiliza las propiedades asociadas
  • Propiedades asociadas en código
  • Metadatos de propiedad asociados
  • Propiedades asociadas personalizadas
  • Obtener más información sobre propiedades asociadas
  • Temas relacionados

Requisitos previos

En este tema se da por sentado que entiende las propiedades de dependencia desde la perspectiva de un consumidor de las propiedades de dependencia existentes en las clases de Windows Presentation Foundation (WPF), y que ha leído Información general sobre las propiedades de dependencia. Para seguir los ejemplos de este tema, también debería entender Extensible Application Markup Language (XAML) y saber escribir aplicaciones de WPF.

Por qué usar propiedades asociadas

Uno de los propósitos de una propiedad asociada es permitir que los diferentes elementos secundarios especifiquen valores únicos para una propiedad que en realidad está definida en un elemento primario. Una aplicación concreta de este escenario es hacer que los elementos secundarios informen al elemento primario de cómo se presentarán en la user interface (UI). Un ejemplo es la propiedad DockPanel.Dock. La propiedad DockPanel.Dock se crea como una propiedad asociada porque se ha diseñado para establecerse en elementos contenidos dentro de un objeto DockPanel, en lugar de en el propio objeto DockPanel. La clase DockPanel define el campo estático DependencyProperty denominado DockProperty y, a continuación, proporciona los métodos GetDock y SetDock como descriptores de acceso públicos para la propiedad asociada.

Propiedades asociadas en XAML

En XAML, las propiedades asociadas se establecen usando la sintaxis ProveedorDePropiedadAsociada.PropertyName. 

A continuación, se muestra un ejemplo de cómo se puede establecer DockPanel.Dock en XAML:

<DockPanel>
  <CheckBox DockPanel.Dock="Top">Hello</CheckBox>
</DockPanel>

Observe que el uso es similar a una propiedad estática; siempre se hace referencia al tipo DockPanel que posee y registra la propiedad asociada, en lugar de hacer referencia a ninguna instancia especificada por nombre.

Además, dado que una propiedad asociada en XAML es un atributo que se establece en el marcado, solamente la operación de establecimiento tiene alguna relevancia. No es posible obtener directamente una propiedad en XAML, aunque hay algunos mecanismos indirectos para comparar valores, tales como desencadenadores en estilos (para ver más detalles, vea Aplicar estilos y plantillas).

Implementación de propiedad asociada en WPF

En Windows Presentation Foundation (WPF), la mayoría de las propiedades asociadas que existen en tipos WPF se implementan como propiedades de dependencia. Las propiedades asociadas son un concepto de XAML, mientras que las propiedades de dependencia son un concepto de WPF. Dado que las propiedades asociadas de WPF son propiedades de dependencia, admiten conceptos de las propiedades de dependencia tales como los metadatos de propiedad y los valores predeterminados de esos metadatos de propiedad.

Cómo el tipo propietario utiliza las propiedades asociadas

Aunque las propiedades asociadas son configurables en cualquier objeto, eso no significa automáticamente que la configuración de la propiedad vaya a producir un resultado tangible, o ni que el valor vaya a ser usado alguna vez por otro objeto. Generalmente, las propiedades adjuntas se conciben de modo que objetos procedentes de una amplia variedad de posibles jerarquías de clases o relaciones lógicas puedan proporcionar información común, cada uno de ellos, al tipo que define la propiedad adjunta. El tipo que define la propiedad asociada sigue normalmente uno de estos modelos:

  • El tipo que define la propiedad asociada se ha diseñado de modo que pueda ser el elemento primario de los elementos que establecerán los valores de la propiedad asociada. El tipo recorre a continuación en iteración sus objetos secundarios mediante lógica interna respecto de alguna estructura de árbol de objetos, obtiene los valores y actúa sobre esos valores de alguna manera.

  • El tipo que define la propiedad asociada se utilizará como elemento secundario para una variedad de posibles elementos principales y modelos de contenido.

  • El tipo que define la propiedad asociada representa un servicio. Otros tipos establecen valores para la propiedad asociada. A continuación, cuando el elemento que estableció la propiedad se evalúa en el contexto del servicio, los valores de la propiedad asociada se obtienen a través de lógica interna de la clase de servicio.

Ejemplo de una propiedad asociada definida por el elemento primario

El escenario más típico donde WPF define una propiedad asociada es cuando un elemento primario admite una colección de elementos secundarios, y también implementa un comportamiento donde los características del comportamiento se indican individualmente para cada elemento secundario.

DockPanel define la DockPanel.Dock propiedad asociada y DockPanel tiene código del nivel de clase como parte de su lógica de representación (específicamente, MeasureOverride y ArrangeOverride). Una instancia de DockPanel siempre comprobará si cualquiera de sus elementos secundarios inmediatos ha establecido un valor para DockPanel.Dock. En ese caso, esos valores se convierten en la entrada para la lógica de representación que se aplica a ese elemento secundario en particular. Cada una de las instancias DockPanel anidadas se ocupa de sus colecciones de elementos secundarios inmediatos, pero ese comportamiento es específico de la manera en que la implementación de DockPanel procesa los valores de DockPanel.Dock. Es teóricamente posible tener propiedades asociadas que influyan sobre elementos más allá del elemento primario inmediato. Si la propiedad asociada de DockPanel.Dock se establece en un elemento que no tiene ningún elemento primario DockPanel sobre el que actuar, no se produce ningún error ni ninguna excepción. Esto significa simplemente que se estableció un valor de propiedad global, pero que no hay ningún elemento primario DockPanel que pueda utilizar la información.

Propiedades asociadas en código

Las propiedades asociadas en WPF no tienen los métodos "contenedores" típicos de CLR para facilitar el acceso se lectura o escritura. Esto se debe a que la propiedad asociada no forma parte necesariamente del espacio de nombres CLR para las instancias donde se establece la propiedad. Sin embargo, un lector de XAML debe poder establecer esos valores cuando se procesa XAML. Para que una propiedad asociada sea efectiva, el tipo propietario de la propiedad asociada debe implementar métodos de descriptor de acceso dedicados en la forma PropertyName y Set PropertyName. Estos métodos de descriptor de acceso dedicados también resultan útiles para obtener o establecer la propiedad adjunta en el código. Desde la perspectiva del código, una propiedad asociada es similar a un campo de apoyo que tiene descriptores de acceso de método en lugar de descriptores de acceso de propiedad; ese campo de apoyo puede existir en cualquier objeto, en lugar de tener que definirse específicamente.

El ejemplo siguiente muestra cómo puede establecer una propiedad asociada en código. En este siguiente ejemplo, myCheckBox es una instancia de la clase CheckBox.

      Dim myDockPanel As New DockPanel()
      Dim myCheckBox As New CheckBox()
      myCheckBox.Content = "Hello"
      myDockPanel.Children.Add(myCheckBox)
      DockPanel.SetDock(myCheckBox, Dock.Top)
DockPanel myDockPanel = new DockPanel();
CheckBox myCheckBox = new CheckBox();
myCheckBox.Content = "Hello";
myDockPanel.Children.Add(myCheckBox);
DockPanel.SetDock(myCheckBox, Dock.Top);

De forma similar al caso de XAML, si myCheckBox no se hubiera sido agregado aún como un elemento secundario de myDockPanel por la tercera línea de código, la cuarta línea de código no produciría una excepción, pero el valor de la propiedad no interactuaría con un elemento primario DockPanel y, por lo tanto, no haría nada. Solamente un valor DockPanel.Dock establecido en un elemento secundario, combinado con la presencia de un elemento primario DockPanel, producirá un comportamiento efectivo en la aplicación representada. (En este caso, se podría establecer la propiedad adjunta y, a continuación, adjuntar al árbol. O bien, se podría adjuntar al árbol y, a continuación, establecer la propiedad adjunta. En ambos casos el resultado es el mismo.)

Metadatos de propiedad asociados

Al registrar la propiedad, FrameworkPropertyMetadata se establece para especificar características de la propiedad como, por ejemplo, si la propiedad afecta a la representación, a la medición, etc. Los metadatos para una propiedad asociada no son diferentes, en general, en una propiedad de dependencia. Si se especifica un valor predeterminado en una invalidación para metadatos de propiedad asociada, ese valor se convierte en el valor predeterminado de la propiedad asociada implícita en instancias de la clase de reemplazo. El valor predeterminado se indica, específicamente, si algún proceso consulta el valor de una propiedad asociada a través del descriptor de acceso de método Get para esa propiedad, especificando una instancia de la clase donde se especificaron los metadatos, y no se ha establecido de ninguna otra manera el valor de esa propiedad asociada.

Si desea habilitar la herencia del valor de la propiedad en una propiedad, es recomendable que utilice propiedades asociadas en lugar de propiedades de dependencia no asociadas. Para obtener información detallada, vea Herencia de valores de propiedad.

Propiedades asociadas personalizadas

Cuándo crear una propiedad asociada

Se puede crear una propiedad asociada cuando haya una razón para tener un mecanismo de configuración de propiedad disponible para clases distintas de la clase de la definición. El escenario más común para ello es el diseño. Ejemplos de propiedades de diseño existentes son DockPanel.Dock, Panel.ZIndex y Canvas.Top. El escenario habilitado aquí es que los elementos que existen como elementos secundarios para los elementos que controlan el diseño pueden expresar individualmente los requisitos de diseño para sus elementos principales de diseño, cada uno de los cuales establece un valor de propiedad que el elemento primario ha definido como una propiedad asociada.

Otro escenario para utilizar una propiedad asociada es cuando la clase representa un servicio y se desea que las clases puedan integrar el servicio de forma más transparente.

Hay otro escenario más compatible con Visual Studio 2008WPF Designer, tal como la edición de ventana Propiedades. Para obtener más información, consulte Información general sobre la creación de controles.

Como ya se ha mencionado, se debe registrar como una propiedad asociada si se desea utilizar la herencia del valor de la propiedad.

Cómo crear una propiedad asociada

Si la clase está definiendo la propiedad asociada estrictamente para el uso en otros tipos, no es necesario que la clase derive de DependencyObject. No obstante, sí deberá derivar de DependencyObject si sigue el modelo WPF general consistente en hacer que la propiedad asociada sea también una propiedad de dependencia.

Defina la propiedad asociada como una propiedad de dependencia declarando un campo public static readonly de tipo DependencyProperty. Para definir este campo, utilice el valor devuelto del método RegisterAttached. El nombre de campo debe coincidir con el nombre de propiedad asociado, al que se anexa la cadena Property, para seguir el modelo WPF establecido de denominar los campos identificadores según las propiedades que representan. El proveedor de la propiedad asociada también debe proporcionar los métodos GetPropertyName y SetPropertyName como descriptores de acceso para la propiedad asociada; si no lo hace, el sistema de propiedades no podrá utilizar la propiedad asociada.

NotaNota

Si omite el descriptor de acceso get de la propiedad adjunta, el enlace de datos en la propiedad no funcionará en las herramientas de diseño, como Visual Studio y Expression Blend.

El descriptor de acceso Get

La firma para el descriptor de acceso GetPropertyName debe ser:

public static object GetPropertyName(object target)

  • El objeto target se puede especificar como un tipo más específico en la implementación. Por ejemplo, el método DockPanel.GetDock establece el tipo del parámetro como UIElement, porque la propiedad asociada solamente está destinada a establecerse en instancias de UIElement.

  • El valor devuelto se puede especificar como un tipo más específico en la implementación. Por ejemplo, el método GetDock define el tipo como Dock, porque el valor solamente se puede establecer en esa enumeración.

El descriptor de acceso Set

La firma para el descriptor de acceso SetPropertyName debe ser:

public static void SetPropertyName(object target, object value)

  • El objeto target se puede especificar como un tipo más específico en la implementación. Por ejemplo, el método SetDock establece el tipo como UIElement, porque la propiedad asociada solamente está destinada a establecerse en instancias de UIElement.

  • El objeto value se puede especificar como un tipo más específico en la implementación. Por ejemplo, el método SetDock define el tipo como Dock, porque el valor solamente se puede establecer en esa enumeración. Recuerde que el valor para este método es la entrada procedente del cargador de XAML cuando encuentra la propiedad asociada en un uso de propiedad asociada en el marcado. Esa entrada es el valor especificado como valor de atributo XAML en el marcado. Por consiguiente, debe haber compatibilidad con conversión de tipos, serializador de valor o extensión de marcado para el tipo que se utilice, de modo que se pueda crear el tipo adecuado a partir del valor del atributo (que, en última instancia, no es nada más que una cadena).

En el ejemplo siguiente se muestra el registro de propiedades de dependencia (usando el método RegisterAttached ), así como los descriptores de acceso GetPropertyName y SetPropertyName. En el ejemplo, el nombre de la propiedad asociada es IsBubbleSource. Por consiguiente, los descriptores de acceso se deben denominar GetIsBubbleSource y SetIsBubbleSource.

Public Shared ReadOnly IsBubbleSourceProperty As DependencyProperty = DependencyProperty.RegisterAttached("IsBubbleSource", GetType(Boolean), GetType(AquariumObject), New FrameworkPropertyMetadata(False, FrameworkPropertyMetadataOptions.AffectsRender))
Public Shared Sub SetIsBubbleSource(ByVal element As UIElement, ByVal value As Boolean)
    element.SetValue(IsBubbleSourceProperty, value)
End Sub
Public Shared Function GetIsBubbleSource(ByVal element As UIElement) As Boolean
    Return CType(element.GetValue(IsBubbleSourceProperty), Boolean)
End Function
public static readonly DependencyProperty IsBubbleSourceProperty = DependencyProperty.RegisterAttached(
  "IsBubbleSource",
  typeof(Boolean),
  typeof(AquariumObject),
  new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender)
);
public static void SetIsBubbleSource(UIElement element, Boolean value)
{
  element.SetValue(IsBubbleSourceProperty, value);
}
public static Boolean GetIsBubbleSource(UIElement element)
{
  return (Boolean)element.GetValue(IsBubbleSourceProperty);
}

Atributos de propiedad asociada

WPF define varios .NET Framework attributes destinados a proporcionar información sobre las propiedades asociadas a los procesos de la reflexión, así como a usuarios típicos de reflexión e información de propiedad tales como los diseñadores. Dado que las propiedades asociadas tienen un tipo de ámbito ilimitado, los diseñadores necesitan una manera de evitar abrumar a los usuarios con una lista global de todas las propiedades asociadas definidas en una determinada implementación de la tecnología que utilice XAML. Los .NET Framework attributes que define WPF para las propiedades asociadas se pueden utilizar para definir el ámbito en aquellas situaciones en las que una propiedad asociada dada deba mostrarse en una ventana de propiedades. También se puede considerar la aplicación de estos atributos para propiedades asociadas propias. El propósito y la sintaxis de los .NET Framework attributes se describen en las páginas de referencia adecuadas:

Obtener más información sobre propiedades asociadas

  • Para obtener más información sobre cómo crear una propiedad asociada, vea Cómo: Registrar una propiedad asociada.

  • Para ver escenarios de uso más avanzado para las propiedades de dependencia y las propiedades asociadas, vea Propiedades de dependencia personalizadas.

  • También es posible registrar una propiedad como una propiedad asociada y como una propiedad de dependencia, pero continuar exponiendo las implementaciones "contenedoras". En este caso, la propiedad se puede establecer en ese elemento o en cualquier otro mediante la sintaxis de la propiedad asociada XAML. Un ejemplo de una propiedad con un escenario adecuado para usos estándar y asociados es FrameworkElement.FlowDirection.

Vea también

Tareas

Cómo: Registrar una propiedad asociada

Referencia

DependencyProperty

Conceptos

Información general sobre las propiedades de dependencia

Propiedades de dependencia personalizadas

Información general sobre XAML (WPF)