Información general sobre las extensiones de marcado para el lenguaje XAMLMarkup Extensions for XAML Overview

Las extensiones de marcado son una técnica XAML para obtener un valor que no es un tipo primitivo ni específico de XAML.Markup extensions are a XAML technique for obtaining a value that is neither a primitive nor a specific XAML type. Para el uso de atributos, las extensiones de marcado usan la secuencia de caracteres conocida de una llave de apertura { para entrar en el ámbito de la extensión de marcado y una llave de cierre } para salir.For attribute usage, markup extensions use the known character sequence of an opening curly brace { to enter the markup extension scope, and a closing curly brace } to exit. Al usar los servicios XAML de .NET Framework, puede usar algunas de las extensiones de marcado del lenguaje XAML predefinidas del ensamblado System.Xaml.When using .NET Framework XAML Services, you can use some of the predefined XAML language markup extensions from the System.Xaml assembly. También puede crear subclases de la clase MarkupExtension , definida en System.Xaml, y definir sus propias extensiones de marcado.You can also subclass from the MarkupExtension class, defined in System.Xaml, and define your own markup extensions. O bien, puede usar las extensiones de marcado definidas por un marco determinado si ya hace referencia a esa plataforma.Or you can use markup extensions defined by a particular framework if you are already referencing that framework.

Cuando se accede al uso de una extensión de marcado, el escritor de objetos XAML puede proporcionar servicios a una clase MarkupExtension personalizada a través de un punto de conexión de servicio en la invalidación MarkupExtension.ProvideValue .When a markup extension usage is accessed, the XAML object writer can provide services to a custom MarkupExtension class through a service connection point in the MarkupExtension.ProvideValue override. Los servicios pueden usarse para obtener contexto sobre el uso, las capacidades concretas del escritor de objetos, el contexto de esquema XAML, etcétera.The services can be used to obtain context about the usage, specific capabilities of the object writer, XAML schema context, and so on.

Extensiones de marcado definidas por XAMLXAML-defined markup extensions

Varias extensiones de marcado se implementan mediante los servicios XAML de .NET Framework para la compatibilidad con el lenguaje XAML.Several markup extensions are implemented by .NET Framework XAML Services for XAML language support. Estas extensiones de marcado corresponden a las partes de la especificación de XAML como lenguaje.These markup extensions correspond to parts of the specification of XAML as a language. Suelen identificarse por el prefijo x: en la sintaxis, tal como se muestra en el uso común.These are typically identifiable by the x: prefix in the syntax as seen in common usage. Los .NET Framework las implementaciones de servicios XAML para estos elementos del lenguaje XAML derivan de la clase base MarkupExtension.The .NET Framework XAML Services implementations for these XAML language elements all derive from the MarkupExtension base class.

Nota

El prefijo x: se usa para la asignación de espacio de nombres típica de XAML para el espacio de nombres del lenguaje XAML, en el elemento raíz de una producción de XAML.The x: prefix is used for the typical XAML namespace mapping of the XAML language namespace, in the root element of a XAML production. Por ejemplo, las plantillas de proyecto y de página de Visual Studio para varios marcos de trabajo específicos inician x: un archivo XAML con esta asignación.For example, the Visual Studio project and page templates for various specific frameworks initiate a XAML file using this x: mapping. Puede elegir un token de prefijo diferente en su propia asignación de espacio de nombres XAML, pero en esta documentación se presupone la asignación x: predeterminada como manera de identificar las entidades que forman una parte definida del espacio de nombres XAML del lenguaje XAML, en lugar de un espacio de nombres XAML predeterminado de un marco concreto o de otros espacios de nombres XML o CLR arbitrarios.You could choose a different prefix token in your own XAML namespace mapping, but this documentation will assume the default x: mapping as a means of identifying those entities that are a defined part of the XAML language XAML namespace, as opposed to a specific framework's default XAML namespace or other arbitrary CLR or XML namespaces.

x:Typex:Type

x:Type proporciona el objeto Type para el tipo con nombre.x:Type supplies the Type object for the named type. Esta funcionalidad se usa con más frecuencia en los mecanismos de aplazamiento que usan el tipo CLR subyacente y la derivación de tipos como identificador o moniker de agrupación.This functionality is used most frequently in deferral mechanisms that use underlying CLR type and type derivation as a grouping moniker or identifier. Los estilos y plantillas WPF y su uso de las propiedades TargetType son un ejemplo concreto.WPF styles and templates, and their usage of TargetType properties, are a specific example. Para obtener más información, consulta x:Type Markup Extension.For more information, see x:Type Markup Extension.

x:Staticx:Static

x:Static genera valores estáticos a partir de entidades de código de tipo de valor que no son directamente el tipo del valor de una propiedad, pero que se pueden evaluar como ese tipo.x:Static produces static values from value-type code entities that are not directly the type of a property's value, but can be evaluated to that type. Esto es útil para especificar valores que ya existen, como constantes conocidas en una definición de tipo.This is useful for specifying values that already exist as well-known constants in a type definition. Para obtener más información, consulta x:Static Markup Extension.For more information, see x:Static Markup Extension.

x:Nullx:Null

x:Null especifica null como valor para un miembro XAML.x:Null specifies null as a value for a XAML member. En función del diseño de tipos específicos o de conceptos de marco más amplios, null no es siempre un valor predeterminado para una propiedad o el valor implícito de un atributo de cadena vacía.Depending on the design of specific types or on larger framework concepts, null is not always a default value for a property, or the implied value of an empty string attribute. Para obtener más información, consulta x:Null Markup Extension.For more information, see x:Null Markup Extension.

x:Arrayx:Array

x:Array admite la creación de matrices generales en sintaxis XAML en los casos en que no se use deliberadamente el soporte de colección que proporcionan los elementos base y los modelos de control.x:Array supports creation of general arrays in XAML syntax in cases where the collection support that is provided by base elements and control models is deliberately not used. Para obtener más información, consulta x:Array Markup Extension.For more information, see x:Array Markup Extension. En concreto en XAML 2009, se accede a las matrices como primitivas del lenguaje, en lugar de como una extensión.In XAML 2009 specifically, arrays are accessed as language primitives instead of as an extension. Para obtener más información, consulta XAML 2009 Language Features.For more information, see XAML 2009 Language Features.

x:Referencex:Reference

x:Reference forma parte de XAML 2009, una extensión del lenguaje original (2006).x:Reference is part of XAML 2009, an extension of the original (2006) language set. x:Reference representa una referencia a otro objeto existente en un gráfico de objetos.x:Reference represents a reference to another existing object in an object graph. Dicho objeto se identifica por su x:Name.That object is identified by its x:Name. Para obtener más información, consulta x:Reference Markup Extension.For more information, see x:Reference Markup Extension.

Otro x: ConstruccionesOther x: Constructs

Existen otras construcciones x: que admiten características del lenguaje XAML, pero no se implementan como extensiones de marcado.Other x: constructs to support XAML language features exist, but these are not implemented as markup extensions. Para obtener más información, vea espacio de nombres XAML (x:) Característicasdel lenguaje.For more information, see XAML Namespace (x:) Language Features.

Clase base MarkupExtensionThe MarkupExtension Base Class

Para definir una extensión de marcado personalizada que pueda interactuar con las implementaciones predeterminadas de los lectores y escritores XAML en System.Xaml, derive una clase de la clase abstracta MarkupExtension .To define a custom markup extension that can interact with the default implementations of XAML readers and XAML writers in System.Xaml, you derive a class from the abstract MarkupExtension class. Dicha la clase tiene que invalidar un método, ProvideValue.That class has one method to override, which is ProvideValue. Puede que también tenga que definir constructores adicionales para admitir los argumentos para el uso de la extensión de marcado, así como propiedades configurables coincidentes.You might also need to define additional constructors to support arguments to the markup extension usage, and matching settable properties.

A través de ProvideValue, una extensión de marcado personalizada tiene acceso a un contexto de servicio que notifica el entorno donde un procesador XAML invoca realmente la extensión de marcado.Through ProvideValue, a custom markup extension has access to a service context that reports the environment where the markup extension is actually invoked by a XAML processor. En la ruta de acceso de carga, suele ser XamlObjectWriter.In the load path this is typically a XamlObjectWriter. En la ruta de acceso de guardado, suele ser XamlXmlWriter.In the save path this is typically a XamlXmlWriter. Cada una informa del contexto de servicio como una clase interna del contexto del proveedor de servicios XAML que implementa un patrón de proveedor de servicios.Each report the service context as an internal XAML service provider context class that implements a service provider pattern. Para más información sobre los servicios disponibles y lo que representan, vea Type Converters and Markup Extensions for XAML.For more information about the available services and what they represent, see Type Converters and Markup Extensions for XAML.

La clase de extensión de marcado debe usar un nivel de acceso público; los procesadores XAML deben ser siempre capaces de crear una instancia de la clase de soporte de la extensión de marcado para usar sus servicios.Your markup extension class must use a public access level; XAML processors must always be able to instantiate the markup extension's support class in order to use its services.

Definir el tipo de compatibilidad para una extensión de marcado personalizadaDefining the Support Type for a Custom Markup Extension

Al usar los servicios XAML de .NET Framework o marcos de trabajo que se basan en los servicios XAML de .NET Framework, tiene dos opciones para asignar un nombre al tipo de compatibilidad de la extensión de marcado.When you use .NET Framework XAML Services or frameworks that build on .NET Framework XAML Services, you have two choices for how to name the markup extension support type. El nombre del tipo es pertinente para la manera en que los escritores de objetos XAML intentan obtener acceso e invocar un tipo de compatibilidad de la extensión de marcado cuando encuentran un uso de la extensión de marcado en XAML.The type name is relevant to how XAML object writers attempt to access and invoke a markup extension support type when they encounter a markup extension usage in XAML. Use una de las siguientes estrategias de nomenclatura:Use one of the following naming strategies:

  • Asigne al tipo un nombre que coincida exactamente con el token de uso del marcado XAML.Name the type name to be an exact match to the XAML markup usage token. Por ejemplo, para admitir el uso de la extensión {Collate ...} , asigne al tipo de compatibilidad el nombre Collate.For example, to support a {Collate ...} extension usage, name the support type Collate.
  • Asigne al tipo un nombre que sea el token de la cadena de uso más el sufijo Extension.Name the type name to be the usage string token plus the suffix Extension. Por ejemplo, para admitir el uso de la extensión {Collate ...} , asigne al tipo de compatibilidad el nombre CollateExtension.For example, to support a {Collate ...} extension usage, name the support type CollateExtension.

Según el orden de búsqueda, primero se busca el nombre de clase con el sufijo Extensiony, a continuación, se busca el nombre de clase sin el sufijo Extension .The order of lookup is to look for the Extension-suffixed class name first and then look for the class name without the Extension suffix.

Desde la perspectiva del uso del marcado, es válido incluir el sufijo Extension como parte del uso.From the markup usage perspective, including the Extension suffix as part of the usage is valid. Sin embargo, esto se comporta como si Extension realmente formase parte del nombre de clase, y los escritores de objetos XAML no podrían resolver una clase de compatibilidad de la extensión de marcado para ese uso si la clase de compatibilidad no tuviese el sufijo Extension .However, this behaves as if Extension is truly part of the class name, and XAML object writers would fail to resolve a markup extension support class for that usage if the support class did not have the Extension suffix.

Constructor sin parámetrosThe parameterless constructor

Para todos los tipos de compatibilidad de la extensión de marcado, debe exponer un constructor sin parámetros público.For all markup extension support types, you should expose a public parameterless constructor. Se requiere un constructor sin parámetros para cualquier caso en el que un escritor de objetos XAML cree una instancia de la extensión de marcado a partir de un uso de elemento de objeto.A parameterless constructor is required for any case where a XAML object writer instantiates the markup extension from an object element usage. La compatibilidad con el uso de elementos de objeto es una expectativa lógica para una extensión de marcado, en especial para la serialización.Supporting object element usage is a fair expectation for a markup extension, particularly for serialization. Sin embargo, puede implementar una extensión de marcado sin un constructor público si solo desea admitir usos de atributos de la extensión de marcado.However, you can implement a markup extension without a public constructor if you only intend to support attribute usages of the markup extension.

Si el uso de la extensión de marcado no tiene ningún argumento, se requiere el constructor sin parámetros para admitir el uso.If your markup extension usage has no arguments, the parameterless constructor is required to support usage.

Patrones de constructor y argumentos posicionales para una extensión de marcado personalizadaConstructor Patterns and Positional Arguments for a Custom Markup Extension

En una extensión de marcado con el uso previsto del argumento, los constructores públicos deben corresponderse con los modos del uso previsto.For a markup extension with intended argument usage, the public constructors must correspond to the modes of the intended usage. En otras palabras, si su extensión de marcado está diseñada para requerir un argumento posicional como uso válido, debe admitir un constructor público con un parámetro de entrada que tome el argumento posicional.In other words, if your markup extension is designed to require one positional argument as a valid usage, you should support a public constructor with one input parameter that takes the positional argument.

Por ejemplo, supongamos que la extensión de marcado Collate está pensada para admitir solo un modo en el que hay un argumento posicional que representa su modo, especificado como una constante de enumeración CollationMode .For example, suppose the Collate markup extension is intended to support only a mode where there is one positional argument that represents its mode, specified as a CollationMode enumeration constant. En este caso, debe haber un constructor con el formato siguiente:In this case, there should be a constructor with the following form:

public Collate(CollationMode collationMode) {...}

En un nivel básico, los argumentos pasados a una extensión de marcado son una cadena, ya que se reenvían desde los valores de atributo del marcado.At a basic level, the arguments passed to a markup extension are a string because they are being forwarded from the markup's attribute values. Puede hacer que todos los argumentos sean cadenas y trabajar con entradas en ese nivel.You can make all of your arguments strings and work with input at that level. Sin embargo, tiene acceso a cierto procesamiento que se produce antes de que los argumentos de extensión de marcado se pasan a la clase de compatibilidad.However, you do have access to certain processing that occurs before the markup extension arguments are passed to the support class.

El procesamiento funciona conceptualmente como si la extensión de marcado fuera un objeto que se va a crear y, a continuación, se establecieran sus valores de miembro.The processing works conceptually as if the markup extension is an object to be created, and then its member values are set. Cada propiedad especificada que se va a establecer se evalúa de modo similar a la manera en que se puede establecer un miembro especificado en un objeto creado cuando se analiza XAML.Each specified property to set is evaluated similar to how a specified member can be set on a created object when XAML is parsed. Hay dos diferencias importantes:There are two important differences:

  • Como se indicó anteriormente, un tipo de compatibilidad de la extensión de marcado no necesita tener un constructor sin parámetros para poder crear instancias en XAML.As noted previously, a markup extension support type does not need to have a parameterless constructor in order to be instantiated in XAML. La construcción de objetos se aplaza hasta que sus posibles argumentos en la sintaxis de texto se conviertan en tokens y se evalúen como argumentos con nombre o posicionales y se llame al constructor adecuado en ese momento.Its object construction is deferred until its possible arguments in the text syntax are tokenized and evaluated as either positional or named arguments, and the appropriate constructor is called at that time.
  • Los usos de las extensiones de marcado se pueden anidar.Markup extensions usages can be nested. Primero se evalúa la extensión de marcado más interna.The innermost markup extension is evaluated first. Por lo tanto, puede suponer este tipo de uso y declarar uno de los parámetros de construcción de modo que sea un tipo que requiere que se genere un convertidor de valores (como una extensión de marcado).Therefore, you can assume such a usage and declare one of the construction parameters to be a type that requires a value converter (such as a markup extension) to produce.

En el ejemplo anterior se mostró una dependencia de este procesamiento.A reliance on such processing was shown in the previous example. El escritor de objetos de servicios XAML de .NET Framework procesa los nombres de constantes de enumeración en valores enumerados en un nivel nativo.The .NET Framework XAML Services XAML object writer processes enumeration constant names into enumerated values at a native level.

El procesamiento de sintaxis de texto de un parámetro posicional de extensión de marcado también puede basarse en un convertidor de tipos que esté asociado al tipo que se encuentra en el argumento de construcción.Processing text syntax of a markup extension positional parameter can also rely on a type converter that is associated with the type that is in the construction argument.

Los argumentos se denominan posicionales porque el orden en que se encuentran los tokens en el uso corresponde al orden posicional del parámetro de constructor al que están asignados.The arguments are called positional arguments because the order in which the tokens in the usage is encountered corresponds to the positional order of the constructor parameter to which they are assigned. Por ejemplo, considere la siguiente firma de constructor:For example, consider the following constructor signature:

public Collate(CollationMode collationMode, object collateThis) {...}

Un procesador XAML espera dos argumentos posicionales para esta extensión de marcado.A XAML processor expects two positional arguments for this markup extension. Si hubo un uso {Collate AlphaUp,{x:Reference circularFile}}, el token AlphaUp se envía al primer parámetro y se evalúa como una enumeración denominada constante CollationMode .If there was a usage {Collate AlphaUp,{x:Reference circularFile}}, the AlphaUp token is sent to the first parameter and evaluated as a CollationMode enumeration named constant. El resultado de la x:Reference interna se envía al segundo parámetro y se evalúa como un objeto.The result of the inner x:Reference is sent to the second parameter and evaluated as an object.

En las reglas especificadas de XAML para la sintaxis y el procesamiento de la extensión de marcado, la coma es el delimitador entre los argumentos, tanto si son argumentos posicionales como argumentos con nombre.In the XAML specified rules for markup extension syntax and processing, the comma is the delimiter between arguments, whether those arguments are positional arguments or named arguments.

Aridad duplicada de argumentos posicionalesDuplicate arity of positional arguments

Si un escritor de objetos XAML encuentra un uso de la extensión de marcado con argumentos posicionales y hay varios argumentos de constructor que toman ese número de argumentos (una aridad duplicada), no se trata necesariamente de un error.If a XAML object writer encounters a markup extension usage with positional arguments, and there are multiple constructor arguments that take that number of arguments (a duplicate arity), that is not necessarily an error. El comportamiento depende de un valor de contexto de esquema XAML personalizable, SupportMarkupExtensionsWithDuplicateArity.The behavior depends on a customizable XAML schema context setting, SupportMarkupExtensionsWithDuplicateArity. Si SupportMarkupExtensionsWithDuplicateArity es true, un escritor de objetos XAML no debería iniciar una excepción solo por razones de aridad duplicada.If SupportMarkupExtensionsWithDuplicateArity is true, a XAML object writer should not throw an exception only for reasons of duplicate arity. El comportamiento a partir de ese punto no está definido estrictamente.Behavior beyond that point is not strictly defined. La hipótesis de diseño básica es que el contexto del esquema tiene información de tipo disponible para los parámetros específicos y puede intentar conversiones explícitas que coinciden con los candidatos duplicados para comprobar qué firma es la mejor coincidencia.The basic design assumption is that the schema context has type information available for the specific parameters and can attempt explicit casts that match the duplicate candidates to see which signature might be the best match. Podría iniciarse igualmente una excepción si ninguna firma supera las pruebas impuestas por el contexto de esquema concreto que se ejecuta en un escritor de objetos XAML.An exception might still be thrown if no signatures can pass the tests that are imposed by that particular schema context that is running on a XAML object writer.

De forma predeterminada, SupportMarkupExtensionsWithDuplicateArity es false en el XamlSchemaContext basado en CLR para servicios XAML de .NET Framework.By default, SupportMarkupExtensionsWithDuplicateArity is false in the CLR-based XamlSchemaContext for .NET Framework XAML Services. Por lo tanto, el XamlObjectWriter predeterminado genera una excepción si encuentra un uso de la extensión de marcado con aridad duplicada en los constructores del tipo de respaldo.Thus, the default XamlObjectWriter throws exceptions if it encounters a markup extension usage where there is duplicate arity in the backing type's constructors.

Argumentos con nombre para una extensión de marcado personalizadaNamed arguments for a custom markup extension

Las extensiones de marcado que especifica XAML también pueden usar un formulario de argumentos con nombre para el uso.Markup extensions as specified by XAML can also use a named arguments form for usage. En el primer nivel de tokenización, la sintaxis de texto se divide en argumentos.At the first level of tokenization, the text syntax is divided into arguments. La presencia de un signo igual (=) en un argumento lo identifica como argumento con nombre.The presence of an equals sign (=) within any argument identifies an argument as a named argument. Dicho argumento también se convierte en token en un par nombre-valor.Such an argument is also tokenized into a name/value pair. En este caso, el nombre designa una propiedad pública configurable del tipo de compatibilidad de la extensión de marcado.The name in this case names a public settable property of the markup extension's support type. Si piensa admitir el uso de argumentos con nombre, debe proporcionar estas propiedades públicas configurables.If you intend to support named argument usage, you should provide these public settable properties. Las propiedades pueden ser heredadas, siempre y cuando sigan siendo públicas.The properties can be inherited properties as long as they remain public.

Acceder al contexto del proveedor de servicios desde una implementación de la extensión de marcadoAccessing Service Provider Context from a Markup Extension Implementation

Los servicios disponibles son los mismos para todos los convertidores de valores.The services available are the same for any value converter. La diferencia radica en la manera en que cada convertidor de valores recibe el contexto de servicio.The difference is in how each value converter receives the service context. El acceso a los servicios y los servicios disponibles se documentan en el tema Type Converters and Markup Extensions for XAML.Accessing services and the services available are documented in the topic Type Converters and Markup Extensions for XAML.

Uso de elementos de propiedad de una extensión de marcadoProperty element usage of a markup extension

Los escenarios para los usos de la extensión de marcado suelen estar diseñados para emplear la extensión de marcado en el uso de atributos.The scenarios for markup extension usages are often designed around using the markup extension in attribute usage. Sin embargo, también es posible definir la clase de respaldo de modo que admita el uso de elementos de propiedad.However, it is also potentially possible to define the backing class to support property element usage.

Para admitir el uso de elementos de propiedad de la extensión de marcado, defina un constructor sin parámetros público.To support property element usage of your markup extension, define a public parameterless constructor. Debe ser un constructor de instancia, no un constructor estático.This should be an instance constructor not a static constructor. Esto es necesario porque un procesador XAML generalmente debe invocar el constructor sin parámetros en cualquier elemento de objeto que procesa desde el marcado, lo que incluye las clases de extensión de marcado como elementos de objeto.This is required because a XAML processor must generally invoke the parameterless constructor on any object element it processes from markup, and this includes markup extension classes as object elements. En el caso de escenarios avanzados, puede definir rutas de acceso de construcción no predeterminadas para las clases.For advanced scenarios, you can define non-default construction paths for classes. (Para obtener más información, vea la Directiva x:FactoryMethod). Sin embargo, no debe usar estos patrones con fines de extensión de marcado, ya que esto dificulta mucho la detección del patrón de uso, tanto a los diseñadores como a los usuarios del marcado sin formato.(For more information, see x:FactoryMethod Directive.) However, you should not use these patterns for markup extension purposes because this makes discovery of the usage pattern much more difficult, both for designers and for users of raw markup.

Atribución para una extensión de marcado personalizadaAttributing for a custom markup extension

Para admitir entornos de diseño y ciertos escenarios del escritor de objetos XAML, debe atribuir varios atributos CLR a un tipo de compatibilidad de la extensión de marcado.To support both design environments and certain XAML object writer scenarios, you should attribute a markup extension support type with several CLR attributes. Estos atributos notifican el uso previsto de la extensión de marcado.These attributes report the intended markup extension usage.

MarkupExtensionReturnTypeAttribute notifica información Type del tipo de objeto que ProvideValue devuelve.MarkupExtensionReturnTypeAttribute reports the Type information for the object type that ProvideValue returns. Por su firma pura, ProvideValue devuelve Object.By its pure signature, ProvideValue returns Object. Sin embargo, algunos consumidores podrían desear información más precisa sobre el tipo de valor devuelto.But various consumers might want more precise return type information. Esto incluye:This includes:

  • Diseñadores e IDE, que pueden proporcionar compatibilidad con reconocimiento del tipo para los usos de la extensión de marcado.Designers and IDEs, who might be able to provide type-aware support for markup extension usages.
  • Implementaciones avanzadas de controladores SetMarkupExtension en las clases de destino, que podrían basarse en la reflexión para determinar el tipo de valor devuelto de una extensión de marcado, en lugar de realizar una bifurcación en implementaciones MarkupExtension conocidas específicas por nombre.Advanced implementations of SetMarkupExtension handlers on target classes, which might rely on reflection to determine a markup extension's return type instead of branching on specific known MarkupExtension implementations by name.

Serialización de los usos de la extensión de marcadoSerialization of markup extension usages

Cuando un escritor de objetos XAML procesa el uso de una extensión de marcado y llama a ProvideValue, el contexto de cuando era el uso de una extensión de marcado se conserva en el flujo de nodo XAML, pero no en el gráfico de objetos.When a XAML object writer processes a markup extension usage and calls ProvideValue, the context for it previously being a markup extension usage persists in the XAML node stream but not in the object graph. En el gráfico de objetos, solo se conserva el valor.In the object graph, only the value is preserved. Si tiene escenarios de diseño u otras razones para conservar el uso de la extensión de marcado original en el resultado serializado, debe diseñar su propia infraestructura para realizar el seguimiento de los usos de la extensión de marcado desde el flujo de nodo XAML de la ruta de acceso de carga.If you have design scenarios or other reasons for persisting the original markup extension usage into the serialized output, you must design your own infrastructure for tracking the markup extension usages from the load path XAML node stream. Puede implementar un comportamiento que vuelva a crear los elementos del flujo de nodo a partir de la ruta de acceso de carga y los reproduzca en escritores XAML para la serialización en la ruta de acceso de guardado, sustituyendo el valor en la posición adecuada del flujo de nodo.You can implement behavior to recreate the elements of the node stream from the load path and play them back to XAML writers for serialization in the save path, substituting for the value in the appropriate position of the node stream.

Extensiones de marcado en el flujo de nodo XAMLMarkup extensions in the XAML node stream

Si está trabajando con un flujo de nodo XAML en la ruta de acceso de carga, el uso de una extensión de marcado aparece como objeto en el flujo de nodo.If you are working with a XAML node stream on the load path, a markup extension usage appears in the node stream as an object.

Si el uso de la extensión de marcado usa argumentos posicionales, se representa como un objeto de inicio con un valor de inicialización.If the markup extension usage uses positional arguments, it is represented as a start object with an initialization value. Como representación de texto aproximada, el flujo de nodo se parece a lo siguiente:As a rough text representation, the node stream resembles the following:

StartObject (XamlType es el tipo de definición de la extensión de marcado, no el tipo de valor devuelto)StartObject (XamlType is the markup extension's definition type, not its return type)

StartMember (el nombre de XamlMember es _InitializationText)StartMember (name of the XamlMember is _InitializationText)

Value (el valor son los argumentos posicionales como cadena, incluidos los delimitadores que intervengan)Value (value is the positional arguments as a string including the intervening delimiters)

EndMember

EndObject

El uso de una extensión de marcado con argumentos con nombre se representa como un objeto con miembros de los nombres correspondientes, cada conjunto de ellos con valores de cadena de texto.A markup extension usage with named arguments is represented as an object with members of the relevant names, each set with text string values.

Para invocar realmente la implementación ProvideValue de una extensión de marcado se requiere el contexto de esquema XAML, ya que es necesaria la asignación de tipos y la creación de una instancia de tipo de compatibilidad de la extensión de marcado.Actually invoking the ProvideValue implementation of a markup extension requires the XAML schema context because that requires type-mapping and creating a markup extension support type instance. Esta es una de las razones por las que los usos de la extensión de marcado se conservan de esta forma en los flujos de nodo predeterminados de los servicios XAML de .NET Framework, ya que la parte del lector de una ruta de acceso de carga no suele tener disponible el contexto de esquema XAML necesario.This is one reason why markup extension usages are preserved this way in the default .NET Framework XAML Services node streams - the reader part of a load path often does not have the necessary XAML schema context available.

Si está trabajando con un flujo de nodo XAML en la ruta de acceso de guardado, no suele haber nada en una representación del gráfico de objetos que informe de que el objeto que se va a serializar se proporcionó originalmente mediante el uso de una extensión de marcado y un resultado ProvideValue .If you are working with a XAML node stream on the save path, there generally is nothing present in an object graph representation that can inform you that the object to serialize was originally provided by a markup extension usage and a ProvideValue result. Los escenarios que necesitan conservar los usos de la extensión de marcado para realizar un recorrido de ida y vuelta y, al mismo tiempo, capturar otros cambios en el gráfico de objetos deben diseñar sus propias técnicas para conservar el conocimiento del uso de una extensión de marcado a partir de la entrada XAML original.Scenarios that need to persist markup extension usages for round-tripping while also capturing other changes in the object graph must devise their own techniques for preserving the knowledge of a markup extension usage from the original XAML input. Por ejemplo, para restaurar los usos de la extensión de marcado, puede que necesite trabajar con el flujo de nodo en la ruta de acceso de guardado para restaurar los usos de la extensión de marcado, o bien realizar algún tipo de combinación entre el XAML original y el XAML de ida y vuelta.For example, to restore the markup extension usages, you may need to work with the node stream on the save path in order to restore markup extension usages, or perform some type of merge between the original XAML and the round-tripped XAML. Algunos marcos que implementan XAML, como WPF, usan tipos intermedios (expresiones) para ayudar a representar casos cuando los usos de la extensión de marcado proporcionaron los valores.Some XAML-implementing frameworks such as WPF use intermediate types (expressions) to help represent cases where markup extension usages provided the values.

Vea tambiénSee also