Terminología de la sintaxis de XAML

Actualización: noviembre 2007

En este tema se definen los términos que se utilizan para describir los elementos de sintaxis de Lenguaje de marcado de aplicaciones extensible (XAML). Estos términos se utilizan con frecuencia en el resto del kit de desarrollo de software (SDK). En este tema se desarrolla la terminología básica introducida en Información general sobre XAML.

Este tema contiene las secciones siguientes.

  • Origen de la terminología de la sintaxis de XAML
  • Sintaxis de elementos de objeto
  • Sintaxis de atributo
  • Sintaxis de elementos de propiedad
  • Sintaxis de contenido XAML
  • Propiedades asociadas
  • Eventos asociados
  • Espacios de nombres XML.
  • Extensiones de marcado
  • Usos opcionales y no recomendados de XAML
  • Temas relacionados

Origen de la terminología de la sintaxis de XAML

La terminología de la sintaxis de XAML definida aquí también se define o se hace referencia a ella dentro de la especificación del lenguaje XAML. XAML es un lenguaje basado en XML y sigue las reglas estructurales de XML. Parte de esta terminología la comparte con o está basada en la terminología utilizada normalmente al describir el lenguaje XML o el Modelo de objetos de documento (DOM) XML.

Sintaxis de elementos de objeto

La sintaxis de elementos de objeto es la sintaxis de marcado de XAML que crea instancias de una clase o estructura common language runtime (CLR) declarando un elemento XML. Esta sintaxis se parece a la sintaxis de elementos de otros lenguajes de marcado, como HTML. La sintaxis de elementos de objeto comienza con un corchete angular izquierdo (<), seguido inmediatamente por el nombre de tipo de la clase o estructura cuyas instancias se van a crear. Puede haber cero o más espacios después del nombre de tipo y se pueden declarar cero o más atributos en el elemento de objeto; cada pareja de nombre de atributo="valor" estará separada por uno o más espacios. Por último, debe cumplirse una de las condiciones siguientes:

  • El elemento y la etiqueta deben cerrarse mediante una barra diagonal (/), seguida inmediatamente por un corchete angular derecho (>).

  • La etiqueta de apertura debe completarse con un corchete angular derecho (>). Dicha etiqueta puede ir seguida de otros elementos de objeto, de elementos de propiedad o de texto interno. El tipo exacto de contenido que se puede incluir aquí viene determinado normalmente por el modelo de objetos del elemento; vea la sección "Sintaxis de contenido" en este mismo tema. También debe existir la etiqueta de cierre equivalente para el elemento de objeto, anidada y equilibrada correctamente con otras parejas de etiquetas de apertura y cierre.

Por ejemplo, el ejemplo siguiente es una sintaxis de elementos de objeto que crea una nueva instancia de la clase Button y también especifica un atributo Name y un valor para ese atributo:

<Button Name="CheckoutButton"/>

El ejemplo siguiente es una sintaxis de elementos de objeto que también incluye la sintaxis de propiedad de contenido de Lenguaje de marcado de aplicaciones extensible (XAML). El texto interno incluido dentro se utilizará para establecer la propiedad de contenido TextBox de Lenguaje de marcado de aplicaciones extensible (XAML), Text.

<TextBox>This is a Text Box</TextBox>

Sintaxis de atributo

La sintaxis de atributo es la sintaxis de marcado de XAML que establece un valor para una propiedad o denomina un controlador de eventos para un evento declarando un atributo en un elemento. El elemento siempre se declara mediante la sintaxis de elementos de objeto. El nombre del atributo debe coincidir con el nombre de miembro de CLR de una propiedad o un evento. El nombre del atributo va seguido de un operador de asignación (=). El valor de atributo debe ser una cadena encerrada entre comillas (").

Para que una propiedad se pueda establecer mediante la sintaxis de atributo, dicha propiedad debe ser pública, de lectura y escritura, y tener un tipo de valor de propiedad del que se puedan crear instancias o al que pueda hacer referencia un procesador de XAML. Para los eventos, el evento debe ser público y tener un delegado público. La propiedad o el evento debe ser un miembro de la clase o estructura de la que el elemento de objeto contenedor crea una instancia.

El valor de atributo se rellena con uno de los valores siguientes, en el orden de procesamiento indicado a continuación:

  1. Si el procesador de XAML encuentra una llave, o un elemento de objeto que deriva de MarkupExtension, se evalúa primero la extensión de marcado a la que se hace referencia en lugar de procesarla como una cadena, y se utiliza el objeto devuelto por la extensión de marcado. En muchos casos, el objeto devuelto por una extensión de marcado no será un objeto nuevo, sino una referencia a un objeto existente o una expresión que aplaza la evaluación hasta el momento de la ejecución.

  2. Si la propiedad se declara con un TypeConverter designado, o el tipo de valor de esa propiedad se declara con un TypeConverter con atributos, el valor de cadena del atributo se envía al convertidor de tipos como una entrada de conversión y el convertidor devolverá una nueva instancia de objeto.

  3. Si no hay TypeConverter, se intenta una conversión directa al tipo de propiedad. Este nivel final es una conversión directa entre tipos primitivos o una comprobación de nombres en una enumeración (que devuelve los valores correspondientes).

Por ejemplo, utilizando el mismo marcado mostrado previamente, el ejemplo siguiente es la sintaxis de atributo utilizada para asignar un valor de cadena a la propiedad Name:

<Button Name="CheckoutButton"/>

La propiedad Name es un miembro de la tabla de miembros para la clase Button. Button es una clase derivada de la clase FrameworkElement que define Name.

Procesamiento de los valores de atributo

El valor de cadena incluido entre las comillas de apertura y cierre es procesado por un procesador de XAML. En el caso de las propiedades, el comportamiento de procesamiento predeterminado está definido por el tipo de propiedad de CLR subyacente. Si la propiedad es un tipo primitivo, el valor de atributo se asigna basándose en la conversión implícita de la cadena al tipo primitivo pertinente. Si la propiedad es una enumeración, la cadena se trata como un nombre definido por dicha enumeración y se devuelve el valor correspondiente de esta. Si la propiedad no es un tipo primitivo ni una enumeración, el valor de atributo se deberá controlar mediante un convertidor de tipos declarado en la misma propiedad o en el tipo de destino. El convertidor de tipos debe proporcionar una conversión que acepte una cadena y debe producir una instancia del tipo de propiedad de CLR subyacente. El paso de la conversión también se podría aplazar mediante una extensión de marcado.

Valores de atributo de enumeración

Los valores de enumeración en XAML son procesados intrínsecamente por los métodos nativos de la estructura Enum.

Para los valores de enumeración sin marcadores, el comportamiento nativo consiste en procesar la cadena de un valor de atributo y resolverlo como uno de los valores de enumeración. La enumeración no se especifica en el formato Enumeración.Valor, tal y como se hace en el código. En su lugar, sólo se especifica Valor, y Enumeración se deduce a partir del tipo de la propiedad que se está estableciendo. Si se especifica un atributo en la forma Enumeración.Valor, no se resolverá correctamente.

Para las enumeraciones basadas en marcadores, el comportamiento está basado en el método Enum.Parse. Se pueden especificar varios valores para una enumeración basada en marcadores separando cada valor con una coma. Sin embargo, no es posible combinar valores de enumeración que no estén basados en marcadores. Por ejemplo, no se puede utilizar la sintaxis de comas para intentar crear un valor Trigger que actúe en varias condiciones de una enumeración sin marcadores:

<!--This will not compile, because Visibility is not a flagwise enumeration.-->
...
<Trigger Property="Visibility" Value="Collapsed,Hidden">
  <Setter ... />
</Trigger>
...

Las enumeraciones basadas en marcadores que admiten atributos que se pueden establecer en XAML no son frecuentes en WPF. Sin embargo, una de estas enumeraciones es StyleSimulations. Por ejemplo, podría utilizar la sintaxis de atributo basada en marcadores y separada por comas para modificar el ejemplo incluido en la sección Comentarios para la clase Glyphs; StyleSimulations = "BoldSimulation" podría convertirse en StyleSimulations = "BoldSimulation,ItalicSimulation". KeyBinding.Modifiers es otra propiedad en la que se pueden especificar varios valores de enumeración. Sin embargo, esta propiedad es un caso especial, ya que la enumeración ModifierKeys admite su propio convertidor de tipos. El convertidor de tipos para los modificadores utiliza un signo más (+) como delimitador en lugar de una coma (,) con objeto de que se pueda utilizar en el marcado la sintaxis más tradicional para representar las combinaciones de teclas, como "Ctrl+Alt".

Referencias a nombres de miembros de evento y de propiedad

Al especificar un atributo, se puede hacer referencia a cualquier propiedad o evento que exista como un miembro del tipo CLR cuya instancia se ha creado para el elemento de objeto contenedor.

O bien, se puede hacer referencia a una propiedad o evento asociado, independiente del elemento de objeto contenedor.

Asimismo, puede asignar un nombre a cualquier evento desde cualquier objeto que sea accesible a través del espacio de nombres predeterminado utilizando un nombre parcial nombreDeTipo.evento; esta sintaxis permite asociar controladores para eventos enrutados en los que el controlador está diseñado para controlar eventos con enrutamiento desde elementos secundarios, pero donde el elemento primario no tiene ese evento en su tabla de miembros. Esta sintaxis se parece a la sintaxis de eventos asociados, pero en este caso el evento no es un verdadero evento asociado. En su lugar, se hace referencia a un evento con un nombre completo. Para obtener más información, consulte Información general sobre eventos enrutados.

Los nombres de las propiedades se proporcionan a veces como el valor de un atributo, no como el nombre de atributo, y dichos nombres también pueden incluir calificadores, como la propiedad especificada en la forma tipoDePropietario.nombreDePropiedadDeDependencia. Este escenario es habitual al crear estilos o plantillas en XAML. Las reglas de procesamiento para los nombres de propiedades proporcionados como un valor de atributo son diferentes, y están regidas por el tipo de propiedad que se va a establecer y por algunos factores del contexto, como que un estilo o una plantilla tenga o no un tipo de destino. Para obtener información más detallada, vea Aplicar estilos y plantillas.

Otro uso para los nombres de propiedades se da cuando un valor de atributo describe una relación entre propiedades. Esta característica se utiliza para el enlace de datos y para los destinos de guión gráfico, y está habilitada por la clase PropertyPath y su convertidor de tipos. Para obtener una descripción más completa de la semántica de búsqueda, vea Sintaxis de PropertyPath de XAML.

Sintaxis de elementos de propiedad

La sintaxis de elementos de propiedad es una sintaxis que difiere ligeramente de la sintaxis XML básica. En XML, el valor de un atributo es de hecho una cadena y la única variación posible es el formato de codificación de cadenas que se utiliza. En XAML, puede asignar otros elementos de objeto como valores de las propiedades. Esta función está habilitada por la sintaxis de elementos de propiedad. En lugar de especificar la propiedad como un atributo dentro de la etiqueta de elemento, la propiedad se especifica utilizando una etiqueta de elemento de apertura en la forma nombreDeTipoElemento.nombreDePropiedad, se especifica el valor de la propiedad y, a continuación, se cierra el elemento de propiedad.

Concretamente, la sintaxis comienza con un corchete angular izquierdo (<), seguido inmediatamente por el nombre de tipo de la clase o estructura en la que está incluida la sintaxis de elementos de propiedad. Esta va seguida inmediatamente de un punto (.), después por el nombre de una propiedad que debe existir dentro de la tabla de miembros del tipo especificado y, a continuación, por un corchete angular derecho (>). El valor que se va a asignar a la propiedad se incluye dentro del elemento de propiedad. Normalmente, el valor se proporciona como uno o más elementos de objeto, porque la especificación de objetos como valores es el escenario que la sintaxis de elementos de propiedad pretende resolver. Finalmente, se debe proporcionar una etiqueta de cierre equivalente que especifique la misma combinación nombreDeTipoElemento.nombreDePropiedad, anidada y equilibrada correctamente con otras etiquetas de elemento. Por ejemplo, la sintaxis siguiente es la sintaxis de elementos de propiedad para la propiedad ContextMenu de un objeto Button.

<Button>
  <Button.ContextMenu>
    <ContextMenu>
      <MenuItem Header="1">First item</MenuItem>
      <MenuItem Header="2">Second item</MenuItem>
    </ContextMenu>
  </Button.ContextMenu>
  Right-click me!</Button>

El valor contenido en un elemento de propiedad también se puede proporcionar como texto interno, en aquellos casos en que el tipo de propiedad que se especifica es un tipo de valor primitivo, como String, o una enumeración en la que se especifica un nombre. Estos dos usos no son habituales, porque cada uno de estos casos también admite la sintaxis de atributo. Un escenario para rellenar un elemento de propiedad con una cadena es para las propiedades que no son la propiedad de contenido XAML pero que se utilizan para la representación de texto de la interfaz de usuario, en el que se requiere que aparezcan elementos de espacio en blanco determinados, como avances de línea. La sintaxis de atributo no puede conservar los avances de línea, pero la sintaxis de elementos de propiedad sí, siempre que esté activa la conservación de espacios en blanco significativos (para obtener más información, vea Procesamiento de espacios en blanco en XAML).

Un elemento de propiedad no se representa en el árbol lógico. Un elemento de propiedad no es más que una sintaxis determinada para establecer una propiedad, y no es ningún elemento que tenga una instancia o un objeto que lo respalde.

Sintaxis de elementos de propiedad para los tipos de colección

La especificación XAML exige a las implementaciones de procesador de XAML que puedan identificar las propiedades cuyo el tipo de valor sea una colección. La implementación de WPF está basada en código administrado, y su procesador de XAML identifica los tipos de colección mediante uno de los mecanismos siguientes:

Si el tipo de una propiedad es una colección, no es necesario especificar en el marcado el tipo de colección que se deduce. En su lugar, los elementos que van a convertirse en elementos de la colección se especifican como uno o más elementos secundarios del elemento de propiedad del tipo de colección. Cada uno de estos elementos se evalúa como un objeto durante la carga y se agrega a la colección llamando al método Add de la colección implícita. Por ejemplo, la propiedad Triggers de Style toma el tipo de colección especializado TriggerCollection. Pero no es necesario crear instancias de un objeto TriggerCollection en el marcado. En su lugar, especifique uno o varios elementos Trigger como elementos dentro del elemento de propiedad Style.Triggers, donde Trigger (o una clase derivada) es el tipo que se espera como tipo de elemento para el objeto TriggerCollection con establecimiento inflexible de tipos e implícito.

<Style x:Key="SpecialButton" TargetType="{x:Type Button}">
  <Style.Triggers>
    <Trigger Property="Button.IsMouseOver" Value="true">
      <Setter Property = "Background" Value="Red"/>
    </Trigger>
    <Trigger Property="Button.IsPressed" Value="true">
      <Setter Property = "Foreground" Value="Green"/>
    </Trigger>
  </Style.Triggers>
</Style>

Una propiedad puede ser tanto un tipo de colección como la propiedad de contenido XAML para dicho tipo y los tipos derivados.

Un elemento de colección implícito crea un miembro en el árbol lógico, aunque no aparece en el marcado como un elemento. Normalmente, el constructor del tipo propietario realiza la creación de instancias para la colección que es una de sus propiedades, lo que permite agregar la colección al árbol.

Nota

La lista genérica y las interfaces de diccionario (IList<T> y IDictionary<TKey, TValue>) no las admite el procesador WPFXAML para la detección de colecciones. Sin embargo, puede utilizar List<T> como una clase base, ya que implementa directamente IList o Dictionary<TKey, TValue>, ya que ésta implementa directamente IDictionary.

Sintaxis de contenido XAML

La sintaxis de contenido XAML es una sintaxis que sólo está habilitada en las clases que especifican ContentPropertyAttribute como parte de su declaración de clase. El objeto ContentPropertyAttribute requiere un parámetro que especifique la propiedad por nombre definida para ser la propiedad de contenido de ese tipo de elemento (incluyendo las clases derivadas). La propiedad así designada es la propiedad de contenido XAML de un elemento. Cuando lo procesa un procesador de XAML, los elementos secundarios o el texto interno que se encuentran entre las etiquetas de apertura y cierre del elemento se asignarán como el valor de esa propiedad de contenido XAML. Puede especificar elementos de propiedad para la propiedad de contenido si lo desea, y hacer explícito su marcado. Esta técnica resulta útil a veces para aumentar la claridad del marcado o por motivos de estilo de marcado; sin embargo, en general la intención de una propiedad de contenido es simplificar el marcado para que los elementos que poseen una relación intuitiva de tipo elemento primario-elemento secundario se puedan anidar directamente. Las etiquetas de los elementos de propiedad de las demás propiedades de un elemento no se asignan como "contenido"; se procesan previamente en el flujo de trabajo del analizador y no se las considera "contenido".

Al igual que cualquier otra propiedad, la propiedad de contenido XAML de un objeto será de un tipo específico. Éste puede ser el tipo Object. El tipo de esa propiedad de contenido ayuda a definir el modelo de contenido de un objeto. Por ejemplo, un tipo de Object es dinámico en el sentido de que cualquier objeto puede convertirse en el contenido, pero incluso esta asignación de tipos dinámica implica que el contenido debe ser un objeto único. El objeto único podría ser un objeto de colección, pero incluso en este caso sólo puede haber un objeto de colección de este tipo asignado como contenido.

En la documentación de WPF, los modelos de contenido para tipos determinados se describen en las páginas de la clase correspondiente a dichos tipos, o se escriben como temas conceptuales independientes para familias de tipos y se vinculan desde cada referencia de tipo pertinente.

Sintaxis de contenido para los tipos de colección

Para aceptar varios elementos de objeto (o texto interno) como contenido, el tipo de la propiedad de contenido debe ser específicamente un tipo de colección. De forma similar a la sintaxis de elementos de propiedad para los tipos de colección, un procesador de XAML debe identificar los tipos que son tipos de colección. Si un elemento tiene una propiedad de contenido XAML y el tipo de la propiedad de contenido XAML es una colección, no es necesario especificar el tipo de colección implícito en el marcado como un elemento de objeto, ni especificar la propiedad de contenido XAML como elemento de propiedad. Por consiguiente, el modelo de contenido aparente en el marcado puede tener ahora varios elementos secundarios asignados como contenido. A continuación se muestra la sintaxis de contenido para una clase derivada de Panel. Todas las clases derivadas de Panel establecen la propiedad de contenido de XAML para que sea Children, lo que requiere un valor de tipo UIElementCollection.

<Page
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  >
  <StackPanel>
    <Button>Button 1</Button>
    <Button>Button 2</Button>
    <Button>Button 3</Button>
  </StackPanel>
</Page>

Observe que ni el elemento de propiedad para Children ni el elemento para UIElementCollection son necesarios en el marcado. Esta es una característica del diseño de XAML, de forma que los elementos incluidos recursivamente que definen una interfaz de usuario se representan de forma más intuitiva como un árbol de elementos anidados con relaciones inmediatas entre los elementos primarios y secundarios, sin etiquetas de elemento de propiedad u objetos de colección intermedios superfluos. De hecho, UIElementCollection no se puede especificar en el marcado como un elemento de objeto, por razones de diseño. Dado que su único uso previsto es como una colección implícita, UIElementCollection no expone un constructor público predeterminado y, por lo tanto, no se pueden crear instancias de él como un elemento de objeto.

Mezclar elementos de propiedad y elementos de objeto en un objeto con una propiedad de contenido

La especificación XAML declara que un procesador de XAML puede exigir que los elementos de objeto que se utilizan para rellenar la propiedad de contenido de XAML dentro de un elemento de objeto sean contiguos y no se mezclen. Esta restricción contra la mezcla de elementos de propiedad y contenido la aplica el procesador de WPFXAML.

Puede utilizar un elemento de objeto secundario como el primer marcado inmediato dentro de un elemento de objeto. A continuación, puede introducir elementos de propiedad. O bien, puede especificar uno o varios elementos de propiedad, seguidos del contenido y, por último, más elementos de propiedad. Pero una vez que un elemento de propiedad sigue al contenido, no se podrá introducir ningún otro tipo de contenido, únicamente se podrán agregar elementos de propiedad.

Este requisito de orden de elemento de contenido/propiedad no se aplica al texto interno utilizado como contenido. Sin embargo, mantener el texto interno contiguo es un buen estilo de marcado, ya que el espacio en blanco significativo será difícil de detectar visualmente en el marcado si los elementos de propiedad están intercalados en el texto interno.

Propiedades asociadas

Las propiedades asociadas son un concepto de programación introducido en XAML según el cual, un tipo puede ser el propietario de las propiedades y definirlas, pero cualquier elemento puede establecerlas. El escenario principal para el que están pensadas las propiedades asociadas es aquél que permite a los elementos secundarios de un árbol de elementos enviar información a un elemento primario sin necesidad de un modelo de objetos compartido por todos los elementos. Y a la inversa, los elementos primarios pueden utilizar las propiedades asociadas para enviar información a los elementos secundarios. Para obtener más información sobre el propósito de las propiedades asociadas y cómo crear sus propias propiedades asociadas, vea Información general sobre propiedades asociadas.

Las propiedades asociadas utilizan una sintaxis que a primera vista es similar a la de los elementos de propiedad, ya que también se debe especificar una combinación nombreDeTipo.nombreDePropiedad. Hay dos diferencias importantes:

  • Puede utilizar la combinación nombreDeTipo.nombreDePropiedad incluso al establecer una propiedad asociada a través de la sintaxis de atributo. Las propiedades asociadas son el único caso en el que certificar el nombre de la propiedad es un requisito en una sintaxis de atributo.

  • También puede utilizar la sintaxis de elementos de propiedad para las propiedades asociadas. Sin embargo, en la sintaxis de elementos de propiedad típica, el nombreDeTipo especificado es el elemento de objeto que contiene el elemento de propiedad. Si está haciendo referencia a una propiedad asociada, el nombreDeTipo es la clase que define la propiedad asociada, no el elemento de objeto contenedor.

Eventos asociados

Los eventos asociados son otro concepto de programación introducido en XAML según el cual, un tipo puede definir los eventos, pero los controladores pueden estar asociados a cualquier objeto. A menudo, el tipo que define un evento asociado es un tipo estático que define un servicio, y algunas veces estos eventos asociados están expuestos por un alias de evento enrutado en los tipos que exponen el servicio. Los controladores para los eventos asociados se especifican mediante la sintaxis de atributo. Al igual que sucede con los eventos asociados, la sintaxis de atributo se expande para los eventos asociados con objeto de permitir el uso de nombreDeTipo.nombreDeEvento, donde nombreDeTipo es la clase que proporciona los descriptores de acceso de controlador de eventos Add y Remove para la infraestructura de evento asociada, y nombreDeEvento es el nombre del evento.

Espacios de nombres XML.

En ninguno de los ejemplos de sintaxis anteriores se especificó un espacio de nombres distinto del predeterminado. En las aplicaciones de WPF típicas se especifica el espacio de nombres WPF como espacio de nombres predeterminado. Puede especificar espacios de nombres distintos del predeterminado y seguir utilizando prácticamente los mismos tipos de sintaxis, pero siempre que se mencione el nombre de una clase a la que no se pueda tener acceso dentro del espacio de nombres predeterminado, dicho nombre debe ir precedido por el prefijo del espacio de nombres XML que se utilizó para asignar el espacio de nombres de CLR correspondiente. Por ejemplo, <custom:MyElement/> es la sintaxis de elementos de objeto para crear una instancia de la clase MyElement, donde el espacio de nombres de CLR que contiene dicha clase (y posiblemente el ensamblado externo que contiene ese espacio de nombres) se asignó previamente al prefijo custom.

Para obtener más información sobre los espacios de nombres de XML y de XAML, vea Espacios de nombres y asignación de espacios de nombres de XAML.

Extensiones de marcado

XAML define una entidad de programación de extensión de marcado que ofrece una vía alternativa al control habitual de atributos o elementos de objetos del procesador de XAML, y cede el procesamiento a una clase de respaldo. La implementación de WPF de un procesador de XAML utiliza la clase abstracta MarkupExtension como base para todas las extensiones de marcado admitidas por WPF. El carácter que identifica una extensión de marcado ante un procesador de XAML al utilizar la sintaxis de atributo es la llave de la apertura ({), seguida por cualquier carácter distinto de una llave de cierre (}). La primera cadena que sigue a la llave de la apertura debe hacer referencia a la clase que proporciona el comportamiento de la extensión en particular, donde la referencia puede omitir la subcadena "Extensión" si dicha subcadena forma parte del nombre de clase verdadero. A partir de ese momento, puede aparecer un solo espacio, y la implementación de extensión utiliza cada carácter subsiguiente como entrada, hasta que se encuentra la llave de cierre. Las extensiones de marcado en WPF están diseñadas principalmente para proporcionar un medio de hacer referencia a otros objetos ya existentes, o referencias diferidas a los objetos que se evaluarán en tiempo de ejecución, mientras se utiliza la sintaxis de atributo. Por ejemplo, un enlace de datos simple se consigue especificando la extensión de marcado {Binding} en lugar del tipo de valor que tomaría normalmente una propiedad determinada. Muchas de las extensiones de marcado permiten la existencia de una sintaxis de atributo para propiedades en las que, de lo contrario, no sería posible una sintaxis de atributo. Por ejemplo, un objeto Style es un tipo de referencia relativamente complejo que contiene varias propiedades, cada una de las cuales también toma objetos byref y no primitivas. Pero los estilos se crean normalmente como un recurso y, a continuación, se hace referencia a ellos mediante una de las dos extensiones de marcado que solicitan un recurso. La extensión cede la evaluación del valor de la propiedad a una búsqueda de recursos y habilita el ofrecer el valor de la propiedad Style, tomando el tipo Style, en la sintaxis de atributo de la manera siguiente:

<Button Style="{StaticResource MyStyle}">My button</Button>

Aquí, StaticResource identifica la clase StaticResourceExtension que proporciona la implementación de la extensión de marcado. La cadena siguiente, MyStyle, se utiliza como la entrada para el constructor StaticResourceExtension no predeterminado, donde el parámetro tal y como se toma de la cadena de extensión declara el objeto ResourceKey solicitado. Se espera que MyStyle sea el valor x:Key (atributo) de un objeto Style definido como recurso. El uso de Extensión de marcado StaticResource requiere que el recurso se utilice para proporcionar el valor de la propiedad Style mediante una lógica de búsqueda de recursos estáticos en el momento de la carga.

Para obtener más información sobre las extensiones de marcado, vea Extensiones de marcado y XAML. Para obtener una referencia de las extensiones de marcado y otras características de programación de XAML, vea Características de lenguaje (x:) de espacios de nombres XAML y Extensiones de XAML de espacio de nombres de WPF.

Usos opcionales y no recomendados de XAML

Usos opcionales de los elementos de propiedad

Los usos opcionales de los elementos de propiedad incluyen ser específico y "detallar" propiedades de contenido de los elementos que el procesador de XAML considera implícitas. Por ejemplo, al declarar el contenido de un objeto Menu, podría optar por declarar explícitamente la colección Items del objeto Menu como una etiqueta de elemento de propiedad <Menu.Items>, y situar cada MenuItem dentro de <Menu.Items> en lugar de utilizar el comportamiento implícito del procesador de XAML, en el que todos los elementos secundarios de un objeto Menu deben ser valores MenuItem y se sitúan en la colección Items. A veces los usos opcionales pueden ayudar a clarificar visualmente la estructura del objeto tal y como se representa en el marcado. En otras ocasiones, el uso explícito de un elemento de propiedad puede evitar un marcado que es técnicamente funcional pero visualmente confuso, como las extensiones de marcado anidadas dentro de un valor de atributo.

Atributos nombreDeTipo.nombreDeMiembro completos

La forma nombreDeTipo.nombreDeMiembro para un atributo en realidad funciona de forma más universal que en el caso de los eventos enrutados, pero en otras aplicaciones dicha forma es superflua y debería evitarse, aunque sólo sea por razones de estilo y legibilidad del marcado. En el ejemplo siguiente, cada una de las tres referencias al atributo Background son completamente equivalentes:

<Button Background="Blue">Background</Button>
<Button Button.Background="Blue">Button.Background</Button>
<Button Control.Background="Blue">Control.Background</Button>

Button.Background funciona porque la búsqueda completa de esa propiedad en el objeto Button se realiza correctamente (Background se ha heredado de Control) y Button es la clase del elemento de objeto o una clase base. Control.Background funciona porque la clase Control define en realidad la propiedad Background y Control es una clase base de Button.

Sin embargo, en el ejemplo siguiente la forma nombreDeTipo.nombreDeMiembro no funciona y, por tanto, se muestra con formato de comentario:

<!--<Button Label.Background="Blue">Does not work</Button> -->

Label es otra clase derivada de Control, y si hubiese especificado Label.Background dentro de un elemento de objeto Label, este uso habría funcionado. Sin embargo, debido a que Label no es la clase o la clase base de Button, el comportamiento especificado del procesador de XAML es procesar Label.Background como una propiedad asociada. Label.Background no es una propiedad asociada y se produce un error en este uso.

Elementos de propiedad nombreDeTipoBase.nombreDeMiembro

La sintaxis nombreDeTipoBase.nombreDeMiembro funciona para la sintaxis de elementos de propiedad de manera análoga a como lo hace nombreDeTipo.nombreDeMiembro en la sintaxis de atributos. Por ejemplo, la sintaxis siguiente funciona:

<Button>Control.Background PE
  <Control.Background>
    <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
      <GradientStop Color="Yellow" Offset="0.0" />
      <GradientStop Color="LimeGreen" Offset="1.0" />
    </LinearGradientBrush>
    </Control.Background>
</Button>

Aquí, el elemento de propiedad se ha proporcionado como Control.Background aunque dicho elemento estaba incluido en Button.

Pero al igual que la forma nombreDeTipo.nombreDeMiembro para los atributos, nombreDeTipoBase.nombreDeMiembro denota un estilo pobre en el marcado y debería evitarlo.

Vea también

Conceptos

Información general sobre XAML

Información general sobre las propiedades de dependencia

Clases TypeConverter y XAML

XAML y clases personalizadas

Otros recursos

Características de lenguaje (x:) de espacios de nombres XAML

Extensiones de XAML de espacio de nombres de WPF