Share via


Extensiones de marcado y XAML

Actualización: noviembre 2007

En este tema se presenta el concepto de extensiones de marcado para Lenguaje de marcado de aplicaciones extensible (XAML), incluidas sus reglas de sintaxis, propósito y modelo de objetos de clase subyacente.

Este tema contiene las secciones siguientes.

  • Procesadores de XAML y extensiones de marcado
  • Sintaxis básica de extensión de marcado
  • Extensiones de marcado específicas de WPF
  • Extensiones de marcado definidas por XAML
  • Más sobre la sintaxis de extensión de marcado
  • Temas relacionados

Procesadores de XAML y extensiones de marcado

Un procesador de XAML se define como cualquier programa que pueda aceptar XAML como lenguaje según sus especificaciones (compilando o interpretando) y generar las clases subyacentes resultantes para su uso por un modelo de objetos en tiempo de ejecución (también según las especificaciones de XAML ). De forma predeterminada, tal procesador interpretará un valor de atributo como una cadena literal o la convertirá en un objeto basándose en el tipo de atributo o en los convertidores de tipos específicos de ese atributo. No obstante, en ocasiones hay escenarios donde se requiere un comportamiento diferente. Por ejemplo, se puede indicar a un procesador de XAML que un valor de un atributo debe ser en su lugar una referencia a un objeto ya construido o a un objeto estático. O bien, se puede indicar a un procesador de XAML que utilice una sintaxis que proporcione argumentos no predeterminados al constructor de un objeto, que es una aberración del comportamiento del procesador de XAML especificado de manera predeterminada.

Sintaxis básica de extensión de marcado

Se puede implementar una extensión de marcado para que proporcione valores para las propiedades de un uso de atributo, las propiedades de un uso de elemento de propiedad o ambas.

Cuando se utiliza para proporcionar un valor de atributo, la sintaxis que distingue una extensión de marcado para un procesador de impresión de XAML es la presencia de llaves de cierre y apertura ({ y }). El token de cadena que sigue inmediatamente a la llave de apertura identifica el tipo de extensión de marcado.

Cuando se utiliza en sintaxis de elemento de propiedad, una extensión de marcado es visualmente igual que cualquier otro elemento utilizado para proporcionar un valor de elemento de propiedad: una declaración de elemento XAML que hace referencia a la clase de extensión de marcado como un elemento, delimitada por corchetes angulares (< >).

Extensiones de marcado específicas de WPF

Las extensiones de marcado más comunes utilizadas en la programación de WPF son las que admiten referencias de recursos (StaticResource y DynamicResource) y las que admiten el enlace de datos (Binding).

StaticResource proporciona un valor para una propiedad XAML sustituyendo el valor de un recurso ya definido. Para obtener información más detallada, vea Extensión de marcado StaticResource.

DynamicResource proporciona un valor para una propiedad XAML aplazando ese valor para que sea una referencia a un recurso en tiempo de ejecución. Una referencia de recurso dinámica fuerza una nueva búsqueda cada vez que se tiene acceso a este tipo de recurso. Para obtener información más detallada, vea Extensión de marcado DynamicResource.

Binding proporciona un valor enlazado a datos para una propiedad, según el contexto de datos que se aplique al elemento. Esta extensión de marcado es relativamente compleja, porque habilita una sintaxis fundamentalmente incluida en el propio código para especificar un enlace de datos. Para obtener información más detallada, vea Enlazar extensión de marcado.

RelativeSource proporciona información de origen para un objeto Binding que puede navegar por varias posibles relaciones en el árbol de elementos en tiempo de ejecución. Esto proporciona una fuente especializada para los enlaces que se crean en plantillas de uso múltiple o se crean en código sin conocimiento completo del árbol de elemento circundante. Para obtener información más detallada, vea Extensión de marcado RelativeSource.

TemplateBinding permite que una plantilla de control utilice valores para propiedades con plantilla procedentes de propiedades definidas por el modelo de objetos de la clase que utilizará la plantilla. Para obtener información más detallada, vea Extensión de marcado TemplateBinding. Para obtener más información sobre el uso práctico de TemplateBinding, vea Ejemplo Styling with ControlTemplates.

Extensiones de marcado definidas por XAML

Existen varias extensiones de marcado que no son específicas de la aplicación WPF de XAML sino que forman parte de la especificación de XAML como lenguaje. Son típicamente identificables por el prefijo x: en la sintaxis, como se ve en el uso común. La implementación de WPF para estos elementos de lenguaje utiliza la misma clase base MarkupExtension para proporcionar la implementación.

Nota

El prefijo x: se utiliza para la asignación típica del espacio de nombres en XAML, en el elemento raíz de una aplicación o documento XAML. Por ejemplo, las plantillas Microsoft Visual Studio 2005 inician un archivo XAML mediante esta asignación x:. Podría elegir un token de prefijo diferente en su propia asignación del espacio de nombres XML, pero en esta documentación se supone la asignación de x: predeterminada como medio de identificar esas entidades que forman una parte definida del espacio de nombres XAML, para diferenciarlas del espacio de nombres WPF o de otros espacios de nombres CLR o XML arbitrarios.

x:Type proporciona el objeto Type para el tipo nombrado. Esto se utiliza con más frecuencia la mayoría en estilos y plantillas. Para obtener información más detallada, vea Extensión de marcado x:Type.

x:Static genera valores estáticos a partir de entidades de código de tipo valor que no son directamente el tipo del valor de una propiedad, pero se pueden evaluar como ese tipo. Para obtener información más detallada, vea Extensiones de marcado x:Static.

x:Null especifica null como valor para una propiedad XAML. Para obtener información más detallada, vea Extensión de marcado x:Null.

x:Array proporciona compatibilidad para la creación de matrices generales en la sintaxis de XAML, para aquellos casos donde el soporte de colección proporcionado por los elementos base y los modelos de control no se utilicen deliberadamente. Para obtener información más detallada, vea Extensión de marcado x:Array.

Más sobre la sintaxis de extensión de marcado

Clases *Extension

El comportamiento de cada extensión de marcado se identifica para un procesador de XAML a través de una clase *Extension que deriva de MarkupExtension y proporciona una implementación del método ProvideValue. Este método define en cada extensión qué objeto se devuelve una vez que se evalúa la extensión de marcado. Lo habitual es que las instancias del objeto devuelto se creen o se establezcan usando los diversos token de cadena pasados a la extensión de marcado.

Por ejemplo, la clase StaticResourceExtension proporciona la implementación de superficie de la búsqueda real de recursos, de modo que su implementación ProvideValue devuelva el objeto que se solicita, siendo la entrada de esa implementación en particular una cadena que se utiliza para buscar el recurso por su x:Key. Gran parte de este detalle de implementación es irrelevante si se está utilizando una extensión de marcado existente.

Interpretación de la clase de extensión de los token de cadena siguientes

Los token de cadena que siguen al identificador de extensión de marcado y continúan estando dentro de las llaves los interpreta un procesador de XAML de una de las siguientes maneras:

  • Una coma siempre representa el separador o el delimitador de token individuales. Por consiguiente una coma literal no se puede pasar a una extensión de marcado.

  • Si los token separados individuales no contienen ningún signo igual, cada token se trata como un argumento de constructor. Cada parámetro de constructor se debe proporcionar como el tipo esperado por esa firma y en el orden apropiado esperado por esa firma.

    Nota

    Un procesador de XAML debe llamar al constructor que coincida con el recuento de argumentos del número de pares. Por esta razón, si está implementando una extensión de marcado personalizada, no proporcione el mismo recuento de argumentos a varios parámetros; lo que ocurre si hay más de un constructor de extensión de marcado con el mismo recuento de parámetros no está definido.

  • Si los token separados individuales contienen signos igual, un procesador de XAML llama primero al constructor predeterminado para la extensión de marcado. A continuación, cada par nombre=valor se interpreta como un nombre de propiedad que existe en la extensión de marcado y un valor que asignar a esa propiedad.

  • Si hay un resultado paralelo entre el comportamiento del constructor y el comportamiento de configuración de propiedad en una extensión de marcado, no importa qué comportamiento utilice. Es más común utilizar los pares propiedad=valor para extensiones de marcado que tengan más de una propiedad configurable, aunque solamente sea porque hace que el marcado sea más calculado y que sea menos probable transponer accidentalmente parámetros de constructor (al especificar los pares propiedad=valor, esas propiedades pueden estar en cualquier orden). Además, no hay ninguna garantía de que una extensión de marcado proporcione un parámetro de constructor que establezca todas sus propiedades configurables. Por ejemplo, Binding es una extensión de marcado, con muchas propiedades que se pueden configurar a través de la extensión en la forma propiedad=valor, pero Binding solamente admite dos constructores: un constructor predeterminado y uno que establece una ruta de acceso inicial.

Escapar de llaves literales

El control de atributos en un procesador de XAML utiliza las llaves como indicadores de una extensión de marcado. También es posible producir un valor de atributo de carácter de llave literal si es necesario, escribiendo una secuencia de escape con un par de llaves vacío seguido por la llave literal. Visite Secuencia de escape / extensión de marcado {}.

Anidar la sintaxis de extensión

Se permite anidar varias extensiones de marcado; en primer lugar se evalúa cada extensión de marcado más profunda, por ejemplo:

<Setter Property="Background"

Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />

Más sobre las extensiones de marcado y la sintaxis de elementos de propiedad

Cuando se utiliza como un elemento de objeto que rellena un valor de elemento de propiedad, una clase de extensión de marcado es visualmente indistinguible de un elemento ordinario que se puede utilizar en XAML. La diferencia práctica entre un elemento ordinario y una extensión de marcado en esta circunstancia es que la extensión de marcado se evalúa como un valor con tipo o se aplaza como una expresión y, por consiguiente, los mecanismos para cualquier posible error de tipo de los valores de la propiedad serán diferentes, de forma similar a como se trata una propiedad enlazada en tiempo de ejecución en otros modelos de programación. Se evaluará el tipo de los elementos ordinario frente a la propiedad que estén estableciendo inmediatamente en la compilación.

La mayoría de las extensiones de marcado, cuando se utilizan en la sintaxis de elemento de objeto para rellenar un elemento de propiedad, no tendrían ningún contenido ni ninguna otra sintaxis de elemento de propiedad y, por lo tanto, se cerraría la etiqueta de elemento del objeto y no se proporcionaría ningún elemento derivado. Siempre que un procesador de XAML encuentra un elemento de objeto, se llama al constructor de esa clase para crear una instancia del objeto creado a partir del elemento analizado. Una clase de extensión de marcado no es diferente; por consiguiente, si se desea que la extensión de marcado sea utilizable en sintaxis de elemento de objeto, se debe proporcionar un constructor predeterminado. Algunas extensiones de marcado existentes tienen por lo menos un valor de propiedad necesario que debe especificarse para la inicialización efectiva y, en ese caso, ese valor de propiedad suele proporcionarse como un atributo de propiedad en el elemento de objeto. En las páginas de referencia Características de lenguaje (x:) de espacios de nombres XAML y Extensiones de XAML de espacio de nombres de WPF se indicarán las extensiones de marcado que tienen propiedades obligatorias (y los nombres de las propiedades obligatorias). Las páginas de referencia también indican si se deniega la sintaxis de elemento de objeto o la sintaxis de atributo para extensiones de marcado determinadas. Un caso notable es Extensión de marcado x:Array, que no admite la sintaxis de atributo porque se debe especificar el contenido de esa matriz. El contenido de la matriz se administra como objetos generales; por consiguiente, no hay ningún convertidor de tipos predeterminado factible para el atributo. Además, Extensión de marcado x:Array requiere un parámetro Type.

Vea también

Conceptos

Información general sobre XAML

Referencia

Extensión de marcado StaticResource

Enlazar extensión de marcado

Extensión de marcado DynamicResource

Extensión de marcado x:Type

Otros recursos

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

Extensiones de XAML de espacio de nombres de WPF