Compartir a través de


Introducción a las estructuras y conceptos de secuencias de nodo XAML

Los sistemas de lectura y escritura XAML implementados en los servicios XAML de .NET Framework se basan en el concepto de diseño de un flujo de nodo XAML. El flujo de nodo XAML es una conceptualización de un conjunto de nodos XAML. En esta conceptualización, un procesador XAML recorre la estructura de relaciones de nodo en el XAML de una en una. En un momento dado solo existe un registro o una posición actual en un flujo de nodo XAML abierto y muchos aspectos de la API indican sólo la información disponible en esa posición. El nodo actual en un flujo de nodo XAML se puede describir como un objeto, un miembro o un valor. Si trata XAML como un flujo de nodo XAML, los lectores de XAML pueden comunicarse con los escritores de XAML y permite a un programa ver, interactuar con el contenido de un flujo de nodo XAML o modificarlo durante una operación de ruta de acceso de carga o ruta de acceso de guardar que implica XAML. El diseño de la API de los sistemas de lectura y escritura XAML y el concepto de flujo de nodo XAML son similares a los diseños y conceptos de sistemas de lectura y escritura relacionados anteriores, como XML Document Object Model (DOM) y las clases XmlReader y XmlWriter. En este tema se discuten los conceptos de flujo de nodo XAML y se describe cómo puede escribir rutinas que interactúan con las representaciones XAML en el nivel de nodo XAML.

Este tema contiene las secciones siguientes.

  • Cargar XAML en un sistema de lectura XAML
  • Un bucle de nodo de lectura básico
  • Trabajar con el nodo actual
  • Atravesar y escribir nodos de objeto
  • Convertidores de valores y flujo de nodo XAML
  • XAML y miembros definidos por el lenguaje XML en el flujo de nodo XAML
  • Orden de los nodos
  • Temas relacionados

Cargar XAML en un sistema de lectura XAML

La clase XamlReader base no declara una técnica determinada para cargar el XAML inicial en un lector de XAML. En su lugar, una clase derivada declara e implementa la técnica de carga, incluidas las características y las restricciones generales de su origen de entrada para XAML. Por ejemplo, XamlObjectReader lee un gráfico de objeto a partir del origen de entrada de un solo objeto que representa la raíz o la base. A continuación, XamlObjectReader genera un flujo de nodo XAML desde el gráfico de objeto.

La subclase XamlReader definida por los Servicios XAML de .NET Framework más prominente es XamlXmlReader. XamlXmlReader carga el XAML inicial cargando un archivo de texto directamente a través de un flujo o ruta de acceso de archivo o indirectamente a través de una clase de lector relacionada, como TextReader. Se puede considerar que XamlReader contiene la totalidad del origen de entrada XAML después de que se ha cargado. Sin embargo, la API base de XamlReader está diseñada para que el lector interactúe con un único nodo del XAML. La primera vez que se carga, el primer nodo que se encuentra es la raíz del XAML y su objeto de inicio.

Concepto de flujo de nodo XAML

Si por lo general está más familiarizado con DOM, la metáfora de árbol o un enfoque basado en consulta para acceder a las tecnologías basadas en XML, una manera útil de conceptualizar un flujo de nodo XAML es la siguiente. Imagine que el XAML cargado es un DOM o un árbol donde cada nodo posible se expande hasta el final y después se presenta de forma lineal. A medida que se avanza por los nodos, es posible que se entre o salga de niveles que serían pertinentes para un DOM pero de los que el flujo de nodo XAML no realiza un seguimiento explícito, porque estos conceptos de nivel no son pertinentes para un flujo de nodo. El flujo de nodo tiene una posición "actual", pero, a menos que haya almacenado otras partes del flujo personalmente como referencia, cada aspecto del flujo de nodo distinto de la posición actual del nodo está fuera de vista.

El concepto de flujo de nodo XAML tiene la gran ventaja de que, si se pasa a través del flujo de nodo completo, es una garantía de que se ha procesado toda la representación de XAML; no es necesario preocuparse de que una consulta, una operación DOM o cualquier otro enfoque no lineal para procesar la información se haya saltado alguna parte de la representación completa de XAML. Por este motivo, la representación del flujo de nodo XAML es ideal tanto para conectar los sistemas de lectura y escritura XAML como para proporcionar un sistema donde se pueda insertar un proceso propio que actúe entre las fases de lectura y escritura de una operación de procesamiento de XAML. En muchos casos, los sistemas de lectura XAML optimizan o reordenan deliberadamente el orden de los nodos en el flujo de nodo XAML, frente al orden que podría aparecer en el texto de origen, binario o gráfico de objeto. Este comportamiento está diseñado para implementar una arquitectura de procesamiento XAML según la cual los sistemas de escritura XAML nunca están en una posición donde tengan que "retroceder" en el flujo de nodo. Idealmente, todas las operaciones de escritura XAML deben ser capaces de actuar según el contexto de esquema más la posición actual del flujo de nodo.

Un bucle de nodo de lectura básico

Un bucle de nodo de lectura básico para examinar un flujo de nodo XAML está compuesto de los siguientes conceptos. A efectos de los bucles de nodo descritos en este tema, supongamos que está leyendo un archivo XAML legible basado en texto mediante XamlXmlReader. Los vínculos de esta sección hacen referencia a la API de bucle de nodo XAML concreta implementada por XamlXmlReader.

  • Asegúrese de que no está en el final del flujo de nodo XAML (compruebe IsEof o use el valor devuelto de Read()). Si está al final del flujo, no hay un nodo actual y debería salir.

  • Compruebe el tipo de nodo que el flujo de nodo XAML expone actualmente llamando a NodeType.

  • Si tiene un sistema de escritura de objetos XAML asociado que esté conectado directamente, normalmente se llama a WriteNode en este punto.

  • En función del objeto XamlNodeType que se notifica como registro actual o nodo actual, llame a uno de los siguientes para obtener información sobre el contenido del nodo:

    • Para unNodeType de StartMember o EndMember, llame a Member para obtener información XamlMember sobre un miembro. Observe que el miembro podría ser XamlDirective y, por consiguiente, no necesariamente tendría que ser un miembro convencional, definido mediante tipo, del objeto anterior. Por ejemplo, x:Name aplicado a un objeto aparece como un miembro XAML donde la propiedad IsDirective es true y la propiedad Name del miembro es Name; las otras propiedades indican que esta directiva está bajo el espacio de nombres XAML del lenguaje XAML.

    • Para un NodeType de StartObject o EndObject, llame a Type para obtener información XamlType sobre un objeto.

    • Para un NodeType de Value, llame a Value. Un nodo es un valor sólo si es la expresión más simple de un valor para un miembro o el texto de inicialización para un objeto (sin embargo, se debe tener en cuenta el comportamiento de conversión de tipos que se describe en una de las secciones siguientes de este tema).

    • Para un NodeType de NamespaceDeclaration, llame a Namespace para obtener información del espacio de nombres para un nodo de espacio de nombres.

  • Llame a Read para avanzar el lector de XAML al nodo siguiente en el flujo de nodo XAML y repita los pasos de nuevo.

El flujo de nodo XAML proporcionado por los Servicios XAML de .NET Framework siempre proporciona un recorrido completo y profundo de todos los posibles nodos. Las técnicas de control de flujo típicas para un bucle de nodo XAML incluyen definir un cuerpo dentro de while (reader.Read()) y activar NodeType en cada punto de nodo en el bucle de nodo.

Si el flujo de nodo está al final del archivo, el nodo actual es null.

El bucle más simple que utiliza un sistema de lectura y escritura es similar al del ejemplo siguiente.

XamlXmlReader xxr = new XamlXmlReader(new StringReader(xamlStringToLoad));
//where xamlStringToLoad is a string of well formed XAML
XamlObjectWriter xow = new XamlObjectWriter(xxr.SchemaContext);
while (xxr.Read()) {
  xow.WriteNode(xxr);
}

Este ejemplo básico de bucle de nodo XAML de una ruta de acceso de carga conecta el lector de XAML y el sistema de escritura de XAML de forma transparente, y su resultado no es diferente del que se obtendría con XamlServices.Parse. Pero a continuación, esta estructura básica se expande para aplicarla al escenario de lectura o escritura. Algunos posibles escenarios son los siguientes:

  • Cambie a NodeType. Realice diferentes acciones dependiendo de qué tipo de nodo se está leyendo.

  • No llame a WriteNode en todos los casos. Llame solo a WriteNode en algunos casos de NodeType.

  • Dentro de la lógica para un tipo de nodo determinado, analice las características concretas de ese nodo y actúe sobre ellas. Por ejemplo, solamente podría escribir objetos que proceden de un espacio de nombres XAML determinado y, a continuación, colocar o diferir cualquier objeto que no proceda de ese espacio de nombres XAML. O bien, podría colocar o volver a procesar de otra forma cualquier directiva XAML que su sistema XAML no admita como parte de su procesamiento del miembro.

  • Defina una clase XamlObjectWriter personalizada que reemplace los métodos Write*, posiblemente realizando la asignación de tipos que omite el contexto de esquema XAML.

  • Construya XamlXmlReader para utilizar un contexto de esquema XAML no predeterminado, de modo que las diferencias personalizadas en el comportamiento de XAML sean utilizadas por el sistema de lectura y de escritura.

Obtener acceso a XAML más allá del concepto de bucle de nodo

Hay posiblemente otras maneras de trabajar con una representación XAML distintas de un bucle de nodo XAML. Por ejemplo, allí podría existir un lector de XAML que puede leer un nodo indizado o en los nodos de acceso particulares directamente mediante x:Name, x:Uid o a través de otros identificadores. Los Servicios XAML de .NET Framework no proporcionan una implementación completa, pero proporcionan un modelo sugerido a través de los servicios y los tipos compatibles. Para obtener más información, vea IXamlIndexingReader y XamlNodeList.

SugerenciaSugerencia

Microsoft también genera una versión fuera de banda conocida como kit de herramientas XAML de Microsoft.Esta versión fuera de banda está todavía en fase de versión preliminar.Sin embargo, si está dispuesto a trabajar con componentes en versión preliminar, el kit de herramientas XAML de Microsoft proporciona algunos recursos interesantes para las herramientas XAML y el análisis estático de XAML.El kit de herramientas XAML de Microsoft incluye una API de DOM XAML, compatibilidad con el análisis de FxCop y un contexto de esquema XAML para Silverlight.Para obtener más información, vea Microsoft XAML Toolkit.

Trabajar con el nodo actual

La mayoría de los escenarios que utilizan un bucle de nodo XAML no solo leen los nodos. La mayoría de los escenarios procesan los nodos actuales y pasan cada nodo de uno en uno a una implementación de XamlWriter.

En un escenario de ruta de acceso de carga típico, XamlXmlReader genera un flujo de nodo XAML, los nodos XAML se procesan según la lógica y el contexto de esquema XAML, y finalmente se pasan a XamlObjectWriter. A continuación, se integra el gráfico de objeto resultante en la aplicación o marco.

Para el escenario de ruta de acceso de guardar típico, XamlObjectReader lee el gráfico de objeto, se procesan los nodos XAML individuales y XamlXmlWriter genera el resultado serializado como un archivo de texto XAML. La clave es que tanto las rutas de acceso como los escenarios implican trabajar exactamente con un nodo XAML a la vez, y los nodos XAML están disponibles para el tratamiento de una manera normalizada que es definida por el sistema de tipos XAML y las API de los Servicios XAML de .NET Framework.

Marcos y ámbito

Un bucle de nodo XAML recorre un flujo de nodo XAML de una manera lineal. El flujo de nodo recorre los objetos, los miembros que contienen otros objetos, etc. A menudo es útil realizar el seguimiento del ámbito en el flujo de nodo XAML mediante la implementación de un concepto de marco y pila. Esto es particularmente cierto si está ajustando activamente el flujo de nodo mientras está en él. La compatibilidad de marco y pila que se implementa como parte de la lógica del bucle de nodo podría contar los ámbitos StartObject (o GetObject) y EndObject a medida que se desciende en una estructura de nodo XAML si la estructura se considera desde una perspectiva de DOM.

Atravesar y escribir nodos de objeto

El primer nodo de un flujo de nodo cuando lo abre un lector de XAML es el nodo del objeto de inicio del objeto raíz. Por definición, este objeto es siempre un nodo de objeto único y no tiene ningún objeto del mismo nivel. En cualquier ejemplo de XAML real, el objeto raíz se define de forma que tenga una o más propiedades que contienen más objetos y estas propiedades tienen nodos miembro. En consecuencia, los nodos de miembro contienen uno o más nodos de objeto o también pueden finalizar en su lugar en un nodo de valor. Normalmente, el objeto raíz define los ámbitos de nombres XAML, que se asignan sintácticamente como atributos en el marcado de texto XAML pero hacen referencia a un tipo de nodo Namescope en la representación del flujo de nodo XAML.

Considere el siguiente ejemplo de XAML (es XAML arbitrario, no respaldado por los tipos existentes en .NET Framework). Suponga que en este modelo de objetos, FavorCollection es List<T> de Favor, Balloon y NoiseMaker son asignables a Favor, un objeto Color respalda la propiedad Balloon.Color de un modo similar a como WPF define los colores como nombres de colores conocidos, y Color admite un convertidor de tipos para la sintaxis de atributo.

Marcado XAML

Flujo de nodo XAML resultante

<Party

Nodo Namespace para Party

xmlns="PartyXamlNamespace">

Nodo StartObject para Party

  <Party.Favors>

Nodo StartMember para Party.Favors

Nodo StartObject para FavorCollection implícito

Nodo StartMember para la propiedad de elementos FavorCollection implícita.

    <Balloon

Nodo StartObject para Balloon

      Color="Red"

Nodo StartMember para Color

  Nodo Value para la cadena de valor de atributo "Red"

EndMember para Color

      HasHelium="True"

Nodo StartMember para HasHelium

  Nodo Value para la cadena de valor de atributo "True"

EndMember para HasHelium

    >

EndObject para Balloon

    <NoiseMaker>Loudest</NoiseMaker>

Nodo StartObject para NoiseMaker

Nodo  StartMember para _Initialization

    Nodo Value para la cadena de valor de inicialización "Loudest"

Nodo  EndMember para _Initialization

EndObject para NoiseMaker

Nodo EndMember para la propiedad de elementos FavorCollection implícita.

Nodo EndObject para FavorCollection implícito

  </Party.Favors>

EndMember para Favors

</Party>

EndObject para Party

En el flujo de nodo XAML, se puede dar por hecho el siguiente comportamiento:

  • Si existe un nodo Namespace, se agrega al flujo inmediatamente antes del StartObject que declaró el espacio de nombres XAML con xmlns. Examine de nuevo la tabla anterior con el XAML y el flujo de nodo de ejemplo. Observe cómo los nodos StartObject y Namespace parecen transponerse contra sus posiciones de declaración en el marcado de texto. Esto es representativo del comportamiento donde los nodos de espacio de nombres siempre aparecen delante del nodo al que se aplican en el flujo de nodo. El propósito de este diseño consiste en que la información de espacio de nombres sea vital para los sistemas de escritura de objetos, y se debe conocer antes de que el sistema de escritura de objeto intente realizar la asignación de tipos o procesar de otra forma el objeto. Colocar la información de espacio de nombres XAML delante de su ámbito de aplicación en el flujo siempre facilita el procesamiento del flujo de nodo en el orden presentado.

  • Debido a la consideración anterior, se trata de uno o más nodos Namespace que se leen primero en la mayoría de los casos de marcado reales al atravesar los nodos desde el inicio, no el StartObject de la raíz.

  • Un nodo StartObject puede ir seguido de StartMember, Value o un EndObject inmediato. Nunca va inmediatamente seguido de otro StartObject.

  • StartMember puede ir seguido de StartObject, Value o un EndMember inmediato. Puede ir seguido de GetObject, para los miembros en los que el valor se supone que procede de un valor existente del objeto primario en lugar de un StartObject que crearía instancias de un nuevo valor. También puede ir seguido de un nodo Namespace, que se aplica a un StartObject siguiente. Nunca va inmediatamente seguido de otro StartMember.

  • Un nodo Value representa el propio valor; no hay ningún "EndValue". Solamente puede ir seguido de un EndMember.

    • El texto de inicialización de XAML del objeto como podría usarlo la construcción no produce una estructura de valor y objeto. En su lugar, se crea un nodo de miembro dedicado para un miembro denominado _Initialization. y ese nodo de miembro contiene la cadena de valor de inicialización. Si existe, _Initialization siempre es el primer StartMember. _Initialization se puede calificar en algunas representaciones de servicios XAML con el ámbito de nombres XAML del lenguaje XAML, para aclarar que _Initialization no es una propiedad definida en los tipos de respaldo.

    • Una combinación de miembro y valor representa un valor de atributo del valor. En última instancia podría aplicarse un convertidor de valores al procesamiento de este valor, y el valor es una cadena sin formato. Sin embargo, esto no se evalúa hasta que un sistema de escritura de objetos XAML procesa este flujo de nodo. El sistema de escritura de objetos XAML posee el contexto de esquema XAML, el sistema de asignación de tipos y otra compatibilidad necesarios para las conversiones de valores.

  • Un nodo StartMember puede ir seguido de un nodo EndMember para un miembro subsiguiente o de un nodo EndObject para el propietario del miembro.

  • Un nodo EndMember puede ir seguido de un nodo EndObject. También puede ir seguido de un nodo StartObject para los casos en que los objetos son del mismo nivel en los elementos de una colección. Alternativamente, puede ir seguido de un nodo Namespace, que se aplica a un StartObject próximo.

    • Para el caso único de cerrar el flujo de nodo completo, el EndObject de la raíz no va seguido de nada; el lector es ahora el fin de archivo y Read devuelve false.

Convertidores de valores y flujo de nodo XAML

Convertidor de valores es un término general para una extensión de marcado, un convertidor de tipos (incluidos los serializadores de valor) u otra clase dedicada que se notifica como un convertidor de valores a través del sistema de tipos XAML. En el flujo de nodo XAML, un uso del convertidor de tipos y un uso de la extensión de marcado tienen representaciones muy diferentes.

Convertidores de tipos en el flujo de nodo XAML

Un conjunto de atributos que finalmente resulta en el uso de un convertidor de tipos se notifica en el flujo de nodo XAML como un valor de un miembro. El flujo de nodo XAML no intenta generar un objeto de instancia de convertidor de tipos, sino pasarle el valor. El uso de una implementación de conversión de un convertidor de tipos requiere invocar el contexto de esquema XAML y utilizarlo para la asignación de tipos. Incluso si se determina qué clase de convertidor de tipos se debería utilizar, para procesar el valor se requiere indirectamente el contexto de esquema XAML. Al utilizar el contexto de esquema XAML predeterminado, esa información está disponible en el sistema de tipos XAML. Si necesita la información de clase del convertidor de tipos en el nivel de flujo de nodo XAML antes de la conexión a un sistema de escritura de XAML, puede obtenerlo en la información de XamlMember del miembro que está estableciendo. En caso contrario, la entrada del convertidor de tipos debe mantenerse en el flujo de nodo XAML como un valor sin formato hasta que se realicen el resto de las operaciones que requieren el sistema de asignación de tipos y el contexto de esquema XAML, como la creación de objetos por un sistema de escritura de objetos XAML.

Por ejemplo, considere el siguiente esquema de definición de clase y el uso de XAML para él:

public class BoardSizeConverter : TypeConverter {
  //converts from string to an int[2] by splitting on an "x" char
}
public class GameBoard {
  [TypeConverter(typeof(BoardSizeConverter))]
  public int[] BoardSize; //2x2 array, initialization not shown
}

<GameBoard BoardSize="8x8"/>

Una representación del texto del flujo de nodo XAML para este uso se puede expresar como sigue:

StartObject con un objeto XamlType que representa GameBoard

StartMember con un objeto XamlMember que representa BoardSize

Nodo Value, con la cadena de texto "8x8"

EndMember coincide con BoardSize.

EndObject coincide con GameBoard.

Observe que no hay ninguna instancia del convertidor de tipos en este flujo de nodo. Pero puede obtener la información del convertidor de tipos llamando a XamlMember.TypeConverter en XamlMember para BoardSize. Si tiene un contexto de esquema XAML válido, también puede invocar los métodos de convertidor obteniendo una instancia de ConverterInstance.

Extensiones de marcado en el flujo de nodo XAML

Un uso de la extensión de marcado se notifica en el flujo de nodo XAML como un nodo de objeto dentro de un miembro, donde el objeto representa una instancia de la extensión de marcado. Por consiguiente, el uso de la extensión de marcado se muestra más explícitamente en la representación del flujo de nodo que el uso del convertidor de tipos, y contiene más información. La información de XamlMember podría no indicarle nada sobre la extensión de marcado, porque el uso es circunstancial y varía en cada posible caso de marcado; no es dedicado ni implícito por tipo o miembro como lo son los convertidores de tipos.

La representación del flujo de nodo de las extensiones de marcado como nodos de objeto es el caso incluso si se ha usado la extensión de marcado en forma de atributo en el marcado de texto XAML (que es a menudo el caso). Los usos de la extensión de marcado que utilizan un formulario de elemento de objeto explícito se tratan de la misma manera.

Dentro de un nodo de objeto de la extensión de marcado, puede haber miembros de esa extensión de marcado. La representación del flujo de nodo XAML conserva el uso de esa extensión de marcado, ya sea un uso de parámetro posicional o un uso con parámetros con nombre explícitos.

Para un uso de parámetro posicional, el flujo de nodo XAML contiene una propiedad _PositionalParameters definida por el lenguaje XAML que graba el uso. Esta propiedad es un objeto List<T> genérico con la restricción Object. La restricción es el objeto y no la cadena porque plausiblemente un uso de parámetro posicional podría contener los usos de la extensión de marcado anidados dentro de él. Para obtener acceso a los parámetros posicionales a partir del uso, podría iterar por la lista y utilizar los indizadores para los valores de lista individuales.

Para un uso del parámetro con nombre, cada parámetro con nombre se representa como un nodo de miembro de ese nombre en el flujo de nodo. Los valores de miembro no son necesariamente cadenas, porque podría producirse un uso anidado de la extensión de marcado.

Todavía no se invoca ProvideValue desde la extensión de marcado. Sin embargo, se invoca si conecta un lector de XAML y un sistema de escritura de XAML de forma que WriteEndObject se invoque en el nodo de la extensión de marcado cuando lo examine en el flujo de nodo. Por esta razón, necesita generalmente tener disponible el mismo contexto de esquema XAML que se utilizaría para formar el gráfico de objetos en la ruta de acceso de carga. De lo contrario, usar ProvideValue en cualquier extensión de marcado puede producir las excepciones que se muestran aquí, porque no están disponibles los servicios esperados.

XAML y miembros definidos por el lenguaje XML en el flujo de nodo XAML

Ciertos miembros se presentan a un flujo de nodo XAML debido a las interpretaciones y convenciones de un lector de XAML, en lugar de presentarse a través de una búsqueda o construcción XamlMember explícita. A menudo, estos miembros son directivas XAML. En algunos casos, es el acto de leer el XAML lo que incluye la directiva en el flujo de nodo XAML. En otras palabras, el texto XAML de entrada original no especifica explícitamente la directiva de miembro, pero el lector XAML inserta la directiva para satisfacer una convención estructural de XAML y la información del informe en el flujo de nodo XAML antes de que se pierda la información.

A continuación se mencionan todos los casos en los que se espera que un lector XAML presente un nodo de miembro de directiva XAML y se muestra cómo se identifica ese nodo de miembro en las implementaciones de los servicios XAML de .NET Framework.

  • Texto de inicialización para un nodo de objeto: el nombre de este nodo de miembro es _Initialization, representa una directiva XAML y se define en el espacio de nombres XAML del lenguaje XAML. Puede recibir de Initialization una entidad estática para este texto.

  • Parámetros posicionales para una extensión de marcado: el nombre de este nodo de miembro es _PositionalParameters y se define en el espacio de nombres XAML del lenguaje XAML. Siempre contiene una lista genérica de objetos, cada uno de los cuales es un parámetro posicional dividido según el carácter delimitador , proporcionado en el XAML de entrada. Puede obtener una entidad estática para la directiva de parámetros posicionales de PositionalParameters.

  • Contenido desconocido: el nombre de este nodo de miembro es _UnknownContent. Hablando estrictamente, es un objeto XamlDirective y se define en el espacio de nombres XAML del lenguaje XAML. Esta directiva se utiliza como un centinela para los casos donde un elemento de objeto XAML incluye el contenido en el XAML de origen, pero no se puede determinar ninguna propiedad de contenido bajo el contexto de esquema XAML actualmente disponible. Puede detectar este caso en un flujo de nodo XAML comprobando los miembros denominados _UnknownContent. Si no se realiza ninguna otra acción en un flujo de nodo XAML de la ruta de acceso de carga, la clase XamlObjectWriter predeterminada produce una excepción en la clase WriteEndObject que se ha intentado cuando encuentre el miembro _UnknownContent en cualquier objeto. La clase XamlXmlWriter predeterminada no produce ninguna excepción y trata el miembro como implícito. Puede recibir de UnknownContent una entidad estática para _UnknownContent.

  • Propiedad de colección de una colección: aunque el tipo CLR de respaldo de una clase de colección que se utiliza para XAML normalmente tiene una propiedad con nombre dedicada que contiene los elementos de la colección, un sistema de tipos XAML no conoce esa propiedad antes de la resolución de los tipos de respaldo. En su lugar, el flujo de nodo XAML presenta un marcador de posición Items como miembro del tipo XAML de la colección. En la implementación de los servicios XAML de .NET Framework, el nombre de esta directiva/miembro en el flujo de nodo es _Items. Se puede obtener una constante de esta directiva de Items.

    Tenga en cuenta que un flujo de nodo XAML puede contener una propiedad Items con elementos que resultan no ser analizables según la resolución de tipos de respaldo y el contexto de esquema XAML. Por ejemplo,

  • Miembros definidos en XML: los miembros definidos en XML xml:base, xml:lang y xml:space se notifican como directivas XAML denominadas base, lang y space en las implementaciones de los servicios XAML de .NET Framework. Su espacio de nombres es XML http://www.w3.org/XML/1998/namespace. Las constantes para cada uno de ellos se pueden obtener de XamlLanguage.

Orden de los nodos

En algunos casos, XamlXmlReader cambia el orden de los nodos XAML en el flujo de nodo XAML, frente al orden los nodos si se ven en el marcado o si se procesan como XML. El propósito de esto es ordenar los nodos de modo que XamlObjectWriter pueda procesar el flujo de nodo solo hacia delante. En los servicios XAML de .NET Framework, el lector XAML reordena los nodos en lugar de permitir que esta tarea la realice el sistema de escritura XAML, como una optimización de rendimiento de los consumidores del sistema de escritura de objetos XAML del flujo de nodo.

Determinadas directivas están diseñadas específicamente para proporcionar más información para la creación de un objeto desde un elemento de objeto. Estas directivas son: Initialization, PositionalParameters, TypeArguments, FactoryMethod, Arguments. Los lectores de los servicios XAML de .NET Framework XAML intentan colocar estas directivas como el primer miembro del flujo de nodo, después del elemento StartObject de un objeto, por los motivos que se describen en la sección siguiente.

Comportamiento de XamlObjectWriter y orden de nodos

El elemento StartObject para un XamlObjectWriter no es necesariamente una señal para que el sistema de escritura construya la instancia de objeto de forma inmediata. XAML incluye varias características de lenguaje que permiten inicializar un objeto con entrada adicional y no basarse completamente en la invocación de un constructor predeterminado para generar el objeto inicial, y únicamente en ese momento establecer las propiedades. Estas características son: XamlDeferLoadAttribute; el texto de inicialización; x:TypeArguments; los parámetros posicionales de una extensión de marcado; los métodos de generador y los nodos x:Arguments asociados (XAML 2009). Cada uno de estos casos retrasa la construcción real del objeto y, como el flujo de nodo se reordena, el sistema de escritura de objetos XAML puede confiar en un comportamiento de construcción real de la instancia siempre que se encuentre un miembro de inicio que no sea específicamente una directiva de construcción de este tipo de objeto.

GetObject

GetObject representa un nodo XAML donde, en lugar de crear un nuevo objeto, un sistema de escritura de objetos XAML debe obtener el valor de la propiedad contenedora del objeto. Un caso común en el que un nodo GetObject se encuentra en un flujo de nodo XAML es el de un objeto de colección o de diccionario, cuando la propiedad contenedora es deliberadamente de solo lectura en el modelo de objetos del tipo de respaldo. En este escenario, es frecuente que la lógica de inicialización de un tipo propietario cree e inicialice la colección o el diccionario (normalmente, vacíos).

Vea también

Referencia

XamlObjectReader

Conceptos

Servicios XAML

Otros recursos

Espacios de nombres XAML para los servicios XAML de .NET Framework