Procesamiento de espacios en blanco en XAML

Las reglas de lenguaje de XAML indican que los espacios en blanco significativos se deben procesar por una implementación de procesador XAML. En este tema se documentan estas reglas del lenguaje XAML. También se documenta el control adicional del espacio en blanco que está definido por la implementación de Windows Presentation Foundation (WPF) del procesador XAML y el sistema de escritura XAML para la serialización.

Definición de espacio en blanco

En coherencia con XML, los caracteres de espacio en blanco en XAML son el espacio, el avance de línea y la tabulación. Estos corresponden a los valores Unicode 0020, 000A y 0009 respectivamente.

Normalización de los espacios en blanco

De manera predeterminada, la normalización siguiente del espacio en blanco se produce cuando un procesador XAML procesa un archivo XAML:

  1. Se quitan los caracteres de avance de línea entre los caracteres de Este de Asia. Consulte la sección "Caracteres de Asia oriental" más adelante en este tema para obtener una definición de este término.

  2. Todos los caracteres de espacio en blanco (espacio, avance de línea, tabulación) se convierten en espacios.

  3. Todos los espacios consecutivos se eliminan y reemplazan por un espacio.

  4. Se elimina el espacio que sigue inmediatamente a la etiqueta inicial.

  5. Se elimina el espacio situado inmediatamente antes de la etiqueta de cierre.

El "valor predeterminado" corresponde al estado indicado por el valor predeterminado del atributo xml:space .

Espacio en blanco en texto interno y primitivas de cadena

Las reglas de normalización anteriores se aplican al texto interno que se encuentra dentro de los elementos XAML. Después de la normalización, un procesador XAML convierte cualquier texto interno en un tipo adecuado, como se indica a continuación:

  • Si el tipo de la propiedad no es una colección, pero no es directamente un tipo Object, el procesador XAML intenta convertirlo a ese tipo con su convertidor de tipos. Una conversión incorrecta aquí producirá un error en tiempo de compilación.

  • Si el tipo de la propiedad es una colección y el texto interno es contiguo (sin etiquetas de elementos intermedias), el texto interno se analiza como una sola String. Si el tipo de colección no puede aceptar String, esto también provoca un error en tiempo de compilación.

  • Si el tipo de la propiedad es Object, el texto interno se analiza como una sola String. Si hay etiquetas de elemento intermedias, se produce un error en tiempo de compilación porque el tipo Object implica que hay un objeto único (de tipoString u otro).

  • Si el tipo de la propiedad es una colección y el texto interno no es contiguo, la primera subcadena se convierte en String y se agrega como un elemento de colección, el elemento intermedio se agrega como un elemento de colección y, por último, la subcadena final (si la hay) se agrega a la colección como un tercer elemento de tipo String .

Preservación de los espacios en blanco

Hay varias técnicas para conservar el espacio en blanco en el origen XAML para la presentación final a las que no afecta la normalización del espacio en blanco del procesador XAML.

xml:space="preserve": especifique este atributo en el nivel del elemento donde desee conservar el espacio en blanco. De esta manera, se conserva todo los espacios en blanco, incluidos los espacios que las aplicaciones de edición de código puedan agregar a los elementos de alineación de "impresión con sangría" como anidamiento visualmente intuitivo. Pero es el modelo de contenido del elemento contenedor el que determina si esos espacios se presentan. Evite especificar xml:space="preserve" en el nivel raíz, porque la mayoría de los modelos de objetos no considera el espacio en blanco como significativo independientemente de cómo se establezca el atributo. La configuración global de xml:space puede tener consecuencias en el rendimiento del procesamiento XAML (en especial la serialización) en algunas implementaciones. Se recomienda limitarse a establecer el atributo específicamente en el nivel de los elementos que presentan el espacio en blanco en las cadenas o que son colecciones significativas de espacios en blanco.

Entidades y espacios de no separación: XAML admite la colocación de cualquier entidad Unicode dentro de un modelo de objetos de texto. Puede usar entidades dedicadas como el espacio sin separación (  en codificación UTF-8). También puede usar controles de texto enriquecido que sean compatibles con caracteres de espacio de no separación. Debe tener cuidado si usa entidades para simular características de diseño tales como la sangría porque la generación de las entidades en tiempo de ejecución dependerá de muchos más factores que los que afectan a la capacidad para aplicar una sangría en un sistema de diseño típico, como el uso correcto de los paneles y los márgenes. Por ejemplo, las entidades se asignan a las fuentes y pueden cambiar el tamaño en respuesta a la selección de fuente del usuario.

Caracteres del Este de Asia

Los caracteres de Asia Oriental se definen como un conjunto de intervalos de caracteres Unicode, de U+20000 a U+2FFFD y de U+30000 a U+3FFFD. En ocasiones, este subconjunto también se denomina "ideogramas CJK". Para obtener más información, vea https://www.unicode.org.

Modelos de contenido de texto y de espacio en blanco

A efectos prácticos, conservar el espacio en blanco solo afecta a un subconjunto de todos los posibles modelos de contenido. Ese subconjunto está compuesto por modelos de contenido que pueden aceptar alguna forma del tipo String singleton, una colección de String dedicada o una mezcla de String y otros tipos en una colección de IList o ICollection<T> .

Modelos de contenido de texto y de espacio en blanco en WPF

Para que sirva de ejemplo, en el resto de esta sección se hace referencia a tipos concretos definidos por WPF. Las características de control de espacios en blanco que se describen en este tema generalmente guardan relación con los servicios XAML de .NET y WPF. Para ver este comportamiento en acción, puede experimentar con el marcado XAML de WPF, ver los resultados en un gráfico de objeto y, después, serializar el marcado de nuevo.

Incluso para los modelos de contenido que pueden aceptar cadenas, el comportamiento predeterminado dentro de estos modelos de contenido consiste en no tratar como significativo el espacio en blanco restante. Por ejemplo, ListBox toma un IList, pero el espacio en blanco (como por ejemplo los avances de línea entre cada ListBoxItem) no se conserva ni se representa. Si intenta usar avances de línea como separadores entre las cadenas de elementos de ListBoxItem , no funcionará en absoluto; las cadenas que están separadas por los avances de línea se tratan como una cadena y un elemento.

Esas colecciones que sí tratan los espacios en blanco como significativos normalmente forman parte del modelo de documentos dinámicos. La colección principal que es compatible con el comportamiento de conservación de espacio en blanco es InlineCollection. Esta clase de colección se declara con WhitespaceSignificantCollectionAttribute; cuando se encuentra este atributo, el procesador XAML trata el espacio en blanco dentro de la colección como significativo. La combinación de xml:space="preserve" y espacio en blanco dentro de una colección indicada con WhitespaceSignificantCollectionAttribute da lugar a que todo el espacio en blanco se conserve y se represente. La combinación de xml:space="default" y de espacio en blanco dentro de un WhitespaceSignificantCollectionAttribute produce la normalización del espacio en blanco inicial descrita anteriormente, que deja un espacio en ciertas posiciones, y que esos espacios se conserven y se representen. El comportamiento deseable depende del usuario, por lo que debe usar xml:space para habilitar el comportamiento que quiera.

Asimismo, algunos elementos en línea que incluyen un avance de línea en un modelo de documentos dinámicos no deberían introducir deliberadamente un espacio adicional ni siquiera en una colección con espacio en blanco significativo. Por ejemplo, el elemento LineBreak tiene el mismo propósito que la etiqueta <BR/> de HTML. Para mejorar la legibilidad del marcado, un LineBreak suele separarse del texto posterior con un avance de línea creado. Ese avance de línea no se debe normalizar para convertirlo en un espacio inicial en la línea posterior. Para habilitar ese comportamiento, la definición de clase del elemento LineBreak aplica TrimSurroundingWhitespaceAttribute, que el procesador XAML interpreta como una indicación de que el espacio en blanco que rodea a LineBreaksiempre se recorta.

Vea también