Compartir a través de


Conceptos y estructuras de flujo de nodo XAML

Los lectores XAML y los escritores XAML implementados en los servicios XAML de .NET se basan en el concepto de diseño de una secuencia de nodos XAML. La secuencia de nodos XAML es una conceptualización de un conjunto de nodos XAML. En esta conceptualización, un procesador XAML recorre la estructura de las relaciones de nodo en el XAML de uno a uno. En cualquier momento, solo existe un registro actual o una posición actual en un flujo de nodo XAML abierto y muchos aspectos de la API solo informan de la información disponible desde esa posición. El nodo actual de un flujo de nodo XAML se puede describir como un objeto, un miembro o un valor. Al tratar XAML como un flujo de nodo XAML, los lectores XAML pueden comunicarse con escritores XAML y permitir que un programa vea, interactúe o modifique el contenido de un flujo de nodo XAML durante una ruta de acceso de carga o una operación de ruta de acceso de guardado que implique XAML. El diseño de la API de lector y escritor XAML y el concepto de flujo de nodos XAML son similares a los diseños y conceptos de lector y escritor relacionados anteriores, como el modelo de objetos de documento XML (DOM) y las clases XmlReader y XmlWriter. En este tema se describen los conceptos de flujo de nodos XAML y se describe cómo se pueden escribir rutinas que interactúan con representaciones XAML en el nivel de nodo XAML.

Carga de XAML en un lector XAML

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

La subclase de servicios XAML de .NET más destacada definida XamlReader es XamlXmlReader. XamlXmlReader carga el XAML inicial, ya sea cargando un archivo de texto directamente a través de una ruta de acceso de secuencia o archivo, o indirectamente a través de una clase de lector relacionada, como TextReader. El XamlReader puede considerarse que contiene la totalidad del origen de entrada XAML después de cargarlo. Sin embargo, la API base de XamlReader está diseñada para que el lector interactúe con un solo nodo del XAML. Cuando se carga por primera vez, el primer nodo que encuentras es la raíz del XAML y su objeto start.

El concepto de flujo de nodos XAML

Si estás más familiarizado con un DOM, una metáfora de árbol o un enfoque basado en consultas para acceder a tecnologías basadas en XML, una manera útil de conceptualizar una secuencia de nodos XAML es la siguiente. Imagine que el XAML cargado es un DOM o un árbol en el que todos los nodos posibles se expanden todo el camino y, a continuación, se presentan linealmente. A medida que avanzas a través de los nodos, es posible que estés cruzando "in" o "out" de niveles que serían relevantes para un DOM, pero la secuencia de nodos XAML no realiza un seguimiento explícitamente porque estos conceptos de nivel no son relevantes para un flujo de nodo. El flujo de nodo tiene una posición "actual", pero a menos que haya almacenado otras partes de la secuencia como referencias, todos los aspectos de la secuencia de nodos que no sean la posición del nodo actual no están disponibles.

El concepto de flujo de nodo XAML tiene la ventaja notable de que, si pasas por todo el flujo de nodo, estás seguro de que has procesado toda la representación XAML; No es necesario preocuparse de que una consulta, una operación DOM o algún otro enfoque no lineal para procesar información ha perdido parte de la representación XAML completa. Por este motivo, la representación de flujo de nodo XAML es ideal para conectar lectores XAML y escritores XAML, y para proporcionar un sistema donde puedes insertar tu propio proceso que actúe entre las fases de lectura y escritura de una operación de procesamiento XAML. En muchos casos, los lectores XAML optimizan o reordenan deliberadamente el orden de los nodos en el flujo de nodos XAML frente a cómo puede aparecer el orden en el gráfico de objetos, binarios o texto de origen. Este comportamiento está pensado para aplicar una arquitectura de procesamiento XAML en la que los escritores XAML nunca están en una posición en la que tienen que volver a "atrás" en el flujo de nodo. Lo ideal es que todas las operaciones de escritura XAML puedan actuar en función del contexto de esquema más la posición actual del flujo de nodo.

Un bucle básico de nodo de lectura

Un bucle básico de nodo de lectura para examinar un flujo de nodo XAML consta de los siguientes conceptos. Para los propósitos de los bucles de nodo tal como se describe en este tema, supongamos que está leyendo un archivo XAML basado en texto y legible mediante XamlXmlReader. Los vínculos de esta sección hacen referencia a la API de bucle de nodo XAML determinada implementada por XamlXmlReader.

  • Asegúrate de que no estás al final del flujo de nodo XAML (comprueba IsEofo usa el valor devuelto de Read). Si está al final de la secuencia, no hay ningún nodo actual y debe salir.

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

  • Si tienes un escritor de objetos XAML asociado conectado directamente, normalmente llamas a WriteNode en este momento.

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

    • Para obtener un NodeType de StartMember o EndMember, llame a Member para obtener XamlMember información sobre un miembro. El miembro puede ser un XamlDirectivey, por tanto, podría no ser necesariamente un miembro convencional definido por tipos del objeto anterior. Por ejemplo, x:Name aplicado a un objeto aparece como miembro XAML donde IsDirective es true y el Name del miembro es Name, con otras propiedades que indican que esta directiva está bajo el espacio de nombres XAML del lenguaje XAML.

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

    • Para una NodeType de Value, llame a Value. Un nodo es un valor solo si es la expresión más sencilla de un valor para un miembro o el texto de inicialización de un objeto (sin embargo, debe tener en cuenta el comportamiento de conversión de tipos como se documenta en una sección próxima de este tema).

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

  • Llame a Read para avanzar el lector XAML al siguiente nodo de la secuencia de nodos XAML y repita los pasos de nuevo.

La secuencia de nodos XAML proporcionada por los lectores XAML de servicios XAML de .NET siempre proporciona un recorrido completo y profundo de todos los nodos posibles. Las técnicas típicas de control de flujo para un bucle de nodo XAML incluyen definir un cuerpo dentro de while (reader.Read())y activar NodeType en cada punto de nodo del bucle del nodo.

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

El bucle más sencillo que usa un lector y escritor es similar al 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 un bucle de nodo XAML de ruta de carga conecta de forma transparente el lector XAML y el escritor XAML, sin hacer nada diferente que si hubiera usado XamlServices.Parse. Pero esta estructura básica se expande para aplicarla al escenario de lectura o escritura. Algunos escenarios posibles son los siguientes:

  • Active NodeType. Realice diferentes acciones en función del tipo de nodo que se está leyendo.

  • No llame a WriteNode en todos los casos. Solo llame a WriteNode en algunos casos NodeType.

  • Dentro de la lógica de un tipo de nodo determinado, analice los detalles de ese nodo y actúe sobre ellos. Por ejemplo, solo se pueden escribir objetos que proceden de un espacio de nombres XAML determinado y, a continuación, quitar o aplazar los objetos que no proceden de ese espacio de nombres XAML. O puedes quitar o volver a procesar cualquier directiva XAML que el sistema XAML no admita como parte del procesamiento de miembros.

  • Defina un XamlObjectWriter personalizado que invalide los métodos Write*, posiblemente realizando la asignación de tipos que omite el contexto del esquema XAML.

  • Construya el XamlXmlReader para usar un contexto de esquema XAML no predeterminado, de modo que el lector y el escritor usen las diferencias personalizadas en el comportamiento XAML.

Acceso a XAML más allá del concepto de bucle de nodo

Hay otras formas de trabajar con una representación XAML distinta de como bucle de nodo XAML. Por ejemplo, podría existir un lector XAML que pueda leer un nodo indizado o, en particular, acceder a los nodos directamente mediante x:Name, por x:Uido a través de otros identificadores. Los servicios XAML de .NET no proporcionan una implementación completa, pero proporciona un patrón sugerido a través de servicios y tipos de soporte técnico. Para obtener más información, consulte IXamlIndexingReader y XamlNodeList.

Trabajar con el nodo actual

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

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

En un escenario típico de ruta de acceso de guardado, un XamlObjectReader lee el gráfico de objetos, se procesan nodos XAML individuales y un 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 estandarizada definida por el sistema de tipos XAML y the.NET API de servicios XAML.

Marcos y ámbito

Un bucle de nodo XAML recorre un flujo de nodo XAML de forma lineal. El flujo de nodo atraviesa objetos, en miembros que contienen otros objetos, etc. A menudo resulta útil realizar un seguimiento del ámbito dentro del flujo de nodos XAML mediante la implementación de un concepto de marco y pila. Esto es especialmente cierto si está ajustando activamente el flujo de nodo mientras está en él. La compatibilidad con fotogramas y pilas que implementes como parte de la lógica del bucle de nodo podría contar StartObject (o GetObject) y EndObject ámbitos a medida que descendes a una estructura de nodo XAML si la estructura se piensa desde una perspectiva DOM.

Recorrido y entrada de nodos de objeto

El primer nodo de un flujo de nodo cuando lo abre un lector XAML es el nodo start-object del objeto raíz. Por definición, este objeto siempre es un nodo de objeto único y no tiene elementos del mismo nivel. En cualquier ejemplo de XAML real, el objeto raíz se define para tener una o varias propiedades que contienen más objetos y estas propiedades tienen nodos de miembro. A continuación, los nodos miembro tienen uno o varios nodos de objeto, o también pueden terminar en un nodo de valor en su lugar. El objeto raíz normalmente define ámbitos de nombres XAML, que se asignan sintácticamente como atributos en el marcado de texto XAML, pero se asignan a un tipo de nodo Namescope en la representación de flujo de nodo XAML.

Considere el ejemplo XAML siguiente (esto es XAML arbitrario, no respaldado por tipos existentes en .NET). Supongamos que, en este modelo de objetos, FavorCollection es List<T> de Favor, Balloon y NoiseMaker se pueden asignar a Favor, la propiedad Balloon.Color está respaldada por un objeto Color similar al modo en que WPF define los colores como nombres de color conocidos y Color admite un convertidor de tipos para la sintaxis de atributos.

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 de StartObject para FavorCollection implícitos
StartMember nodo para la propiedad de elementos FavorCollection implícitos.
<Balloon nodo StartObject para Balloon
Color="Red" nodo StartMember para Color

Value nodo de la cadena de valor de atributo "Red"

EndMember para Color
HasHelium="True" nodo StartMember para HasHelium

Value nodo de la cadena de valor de atributo "True"

EndMember para HasHelium
> EndObject para Balloon
<NoiseMaker>Loudest</NoiseMaker> nodo StartObject para NoiseMaker

nodo StartMember para _Initialization

Value nodo de la cadena de valor de inicialización "Loudest"

nodo EndMember para _Initialization

EndObject para NoiseMaker
EndMember nodo para la propiedad de elementos FavorCollection implícitos.
nodo de EndObject para FavorCollection implícitos
</Party.Favors> EndMember para Favors
</Party> EndObject para Party

En el flujo de nodo XAML, puedes confiar en el siguiente comportamiento:

  • Si existe un nodo Namespace, se agrega a la secuencia inmediatamente antes del StartObject que declaró el espacio de nombres XAML con xmlns. Examine de nuevo la tabla anterior con el flujo de nodo XAML y de ejemplo. Observe cómo parece que los nodos StartObject y Namespace se transponen frente a sus posiciones de declaración en el marcado de texto. Esto es representativo del comportamiento en el que 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 es que la información del espacio de nombres es fundamental para los escritores de objetos y debe conocerse antes de que el escritor de objetos intente realizar la asignación de tipos o procesar el objeto de otro modo. Colocar la información del espacio de nombres XAML delante de su ámbito de aplicación en la secuencia hace que sea más fácil procesar siempre el flujo de nodo en su orden presentado.

  • Debido a la consideración anterior, es uno o varios nodos Namespace que se leen primero en la mayoría de los casos de marcado del mundo real al atravesar nodos desde el principio, no el StartObject de la raíz.

  • Un nodo StartObject puede ir seguido de StartMember, Valueo un EndObjectinmediato. Nunca va seguido inmediatamente de otro StartObject.

  • Un StartMember puede ir seguido de un StartObject, Valueo un EndMemberinmediato . Puede ir seguido de GetObject, para los miembros en los que se supone que el valor procede de un valor existente del objeto primario en lugar de un StartObject que crearía una instancia de un nuevo valor. También puede ir seguido de un nodo de Namespace, que se aplica a una próxima StartObject. Nunca va seguido inmediatamente de otro StartMember.

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

    • El texto de inicialización XAML del objeto como podría usarse en la construcción no da lugar a una estructura de Object-Value. En su lugar, se crea un nodo de miembro dedicado para un miembro denominado _Initialization. y ese nodo miembro contiene la cadena de valor de inicialización. Si existe, _Initialization siempre es el primer StartMember. _Initialization puede calificarse 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 tipos de respaldo.

    • Una combinación Member-Value representa un valor de atributo del valor. Eventualmente, podría haber un convertidor de valores implicado en el procesamiento de este valor y el valor es una cadena sin formato. Sin embargo, esto no se evalúa hasta que un escritor de objetos XAML procesa este flujo de nodo. El escritor de objetos XAML posee el contexto de esquema XAML necesario, la asignación del sistema de tipos y otra compatibilidad necesaria para las conversiones de valores.

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

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

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

Convertidores de valores y el flujo de nodo XAML

Un convertidor de valores es un término general para una extensión de marcado, un convertidor de tipos (incluidos serializadores de valor) u otra clase dedicada que se notifica como 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 extensión de marcado tienen representaciones muy diferentes.

Convertidores de tipos en el flujo de nodos XAML

Un conjunto de atributos que finalmente da como resultado un uso del 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 del convertidor de tipos y pasar el valor a él. El uso de la implementación de conversión de un convertidor de tipos requiere invocar el contexto de esquema XAML y usarlo para la asignación de tipos. Incluso determinar qué clase de convertidor de tipos se debe usar para procesar el valor requiere el contexto de esquema XAML indirectamente. Cuando usas el contexto de esquema XAML predeterminado, esa información está disponible en el sistema de tipos XAML. Si necesitas la información de la clase de convertidor de tipos en el nivel de flujo de nodo XAML antes de la conexión a un escritor XAML, puedes obtenerla de la información XamlMember del miembro que se establece. Pero, de lo contrario, la entrada del convertidor de tipos debe conservarse en el flujo de nodo XAML como un valor sin formato hasta el resto de las operaciones que requieren el sistema de asignación de tipos y el contexto de esquema XAML se realizan, por ejemplo, la creación del objeto por un escritor de objetos XAML.

Por ejemplo, considere el siguiente esquema de definición de clase y uso 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 de texto del flujo de nodo XAML para este uso podría expresarse como la siguiente:

StartObject con XamlType que representan GameBoard

StartMember con XamlMember que representan BoardSize

Value nodo, con 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 información del convertidor de tipos llamando a XamlMember.TypeConverter en el XamlMember para BoardSize. Si tienes un contexto de esquema XAML válido, también puedes invocar los métodos de convertidor obteniendo una instancia de ConverterInstance.

Extensiones de marcado en el flujo de nodo XAML

El uso de una 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 extensión de marcado. Por lo tanto, se presenta un uso de extensión de marcado más explícitamente en la representación del flujo de nodo que el uso de un convertidor de tipos y contiene más información. XamlMember información no pudo haberle dicho nada sobre la extensión de marcado, ya que el uso es situacional y varía en cada caso de marcado posible; no es dedicado e implícito por tipo o miembro, como sucede con convertidores de tipos.

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

Dentro de un nodo de objeto de 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ámetros posicionales o un uso con parámetros con nombre explícito.

Para un uso de parámetros posicionales, la secuencia de nodos XAML contiene una propiedad definida por el lenguaje XAML _PositionalParameters que registra el uso. Esta propiedad es un List<T> genérico con restricción Object. La restricción es el objeto y no la cadena porque, concebiblemente, un uso de parámetros posicionales podría contener usos de extensiones de marcado anidadas dentro de ella. Para acceder a los parámetros posicionales desde el uso, puede recorrer en iteración la lista y usar los indexadores para valores de lista individuales.

Para un uso de parámetros con nombre, cada parámetro con nombre se representa como un nodo miembro de ese nombre en la secuencia de nodos. Los valores de miembro no son necesariamente cadenas, ya que podría haber un uso de extensión de marcado anidado.

ProvideValue de la extensión de marcado aún no se ha invocado. Sin embargo, se invoca si conecta un lector XAML y un escritor XAML para que se invoque WriteEndObject en el nodo de extensión de marcado al examinarlo en la secuencia de nodos. Por este motivo, normalmente necesitas el mismo contexto de esquema XAML disponible que se usaría para formar el gráfico de objetos en la ruta de acceso de carga. De lo contrario, ProvideValue de cualquier extensión de marcado puede producir excepciones aquí, ya que no tiene los servicios esperados disponibles.

Miembros de Language-Defined XAML y XML en el flujo de nodo XAML

Algunos miembros se introducen en una secuencia de nodos XAML debido a interpretaciones y convenciones de un lector XAML, en lugar de a través de una búsqueda o construcción explícitas de XamlMember. A menudo, estos miembros son directivas XAML. En algunos casos, es el acto de leer el XAML que introduce la directiva en el flujo de nodo XAML. En otras palabras, el texto XAML de entrada original no especificó explícitamente la directiva miembro, pero el lector XAML inserta la directiva para satisfacer una convención XAML estructural e información de informe en el flujo de nodo XAML antes de que se pierda esa información.

En la lista siguiente se indican todos los casos en los que se espera que un lector XAML introduzca un nodo miembro XAML de directiva y cómo se identifica ese nodo miembro en las implementaciones de servicios XAML de .NET.

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

  • parámetros posicionales para una extensión de marcado: El nombre de este nodo miembro es _PositionalParametersy 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 separado previamente por la división en el carácter delimitador de , tal como se proporciona 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 miembro es _UnknownContent. En términos estrictos, es un XamlDirectivey se define en el espacio de nombres XAML del lenguaje XAML. Esta directiva se usa como centinela para los casos en los que un elemento de objeto XAML contiene contenido en el XAML de origen, pero no se puede determinar ninguna propiedad de contenido en el contexto de esquema XAML disponible actualmente. Puedes 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 ruta de carga, el XamlObjectWriter predeterminado se produce al intentar WriteEndObject cuando encuentra el miembro _UnknownContent en cualquier objeto. El XamlXmlWriter predeterminado no inicia y trata al miembro como implícito. Puede obtener una entidad estática para _UnknownContent de UnknownContent.

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

    Tenga en cuenta que un flujo de nodo XAML puede contener una propiedad Items con elementos que no se puedan analizar en función de la resolución de tipos de respaldo y el contexto de esquema XAML. Por ejemplo

  • miembros definidos por XML: los miembros definidos por XML xml:base, xml:lang y xml:space se notifican como directivas XAML denominadas base, langy space en implementaciones de servicios XAML de .NET. El espacio de nombres para estos es el espacio de nombres XML http://www.w3.org/XML/1998/namespace. Las constantes de cada una de estas se pueden obtener de XamlLanguage.

Orden del nodo

En algunos casos, XamlXmlReader cambia el orden de los nodos XAML en el flujo de nodos XAML, frente al orden en que aparecen los nodos si se ven en el marcado o si se procesan como XML. Esto se hace para ordenar los nodos de forma que un XamlObjectWriter pueda procesar el flujo de nodos de forma de solo avance. En los servicios XAML de .NET, el lector XAML reordena los nodos en lugar de dejar esta tarea en el escritor XAML, como una optimización del rendimiento para los consumidores del escritor de objetos XAML de la secuencia de nodos.

Algunas directivas están diseñadas específicamente para proporcionar más información para la creación de un objeto a partir de un elemento de objeto. Estas directivas son: Initialization, PositionalParameters, TypeArguments, FactoryMethod, Arguments. Los lectores XAML de servicios XAML de .NET intentan colocar estas directivas como los primeros miembros del flujo de nodo después de la StartObjectde un objeto, por motivos que se explican en la sección siguiente.

Comportamiento de XamlObjectWriter y orden de nodo

StartObject a un XamlObjectWriter no es necesariamente una señal al escritor de objetos XAML para construir inmediatamente la instancia de objeto. XAML incluye varias características de lenguaje que permiten inicializar un objeto con una entrada adicional y no confiar completamente en invocar un constructor sin parámetros para generar el objeto inicial y, a continuación, establecer las propiedades. Estas características incluyen: ; texto de inicialización; x:TypeArguments; parámetros posicionales de una extensión de marcado; métodos de fábrica y nodos de asociados x:Arguments (XAML 2009). Cada uno de estos casos retrasa la construcción del objeto real y, dado que el flujo de nodo se reordena, el escritor de objetos XAML puede basarse en un comportamiento de construcción de la instancia cada vez que se encuentra un miembro inicial que no es específicamente una directiva de construcción para ese tipo de objeto.

GetObject

GetObject representa un nodo XAML en el que, en lugar de construir un nuevo objeto, un escritor de objetos XAML debe obtener en su lugar el valor de la propiedad contenedora del objeto. Un caso típico en el que se encuentra un nodo GetObject en un flujo de nodo XAML es para un objeto de colección o un objeto de diccionario, cuando la propiedad contenedora es deliberadamente de solo lectura en el modelo de objetos del tipo de respaldo. En este escenario, la colección o diccionario a menudo se crea e inicializa (normalmente vacía) mediante la lógica de inicialización de un tipo propietario.

Consulte también