Definir tipos personalizados para usarlos con los servicios XAML de .NETDefine custom types for use with .NET XAML Services

Al definir tipos personalizados que son objetos de negocio o que son tipos que no tienen una dependencia en marcos de trabajo específicos, se pueden seguir algunas prácticas recomendadas para XAML.When you define custom types that are business objects or are types that do not have a dependency on specific frameworks, there are certain best practices for XAML you can follow. Si sigue estos procedimientos, los servicios XAML de .NET y sus lectores XAML y escritores de XAML pueden detectar las características XAML de su tipo y proporcionar una representación adecuada en un flujo de nodo XAML mediante el sistema de tipos XAML.If you follow these practices, .NET XAML Services and its XAML readers and XAML writers can discover the XAML characteristics of your type and give it appropriate representation in a XAML node stream using the XAML type system. En este tema se describen los procedimientos recomendados para definiciones de tipo, definiciones de miembro y atribución de CLR de tipos o miembros.This topic describes best practices for type definitions, member definitions, and CLR attributing of types or members.

Patrones de constructor y definiciones de tipos para XAMLConstructor Patterns and Type Definitions for XAML

Para crear instancias como un elemento de objeto en XAML, una clase personalizada debe cumplir los siguientes requisitos:To be instantiated as an object element in XAML, a custom class must meet the following requirements:

  • La clase personalizada debe ser pública y debe exponer un constructor público sin parámetros.The custom class must be public and must expose a parameterless public constructor. (Vea en la siguiente sección las notas relativas a las estructuras).(See following section for notes regarding structures.)

  • La clase personalizada no debe ser una clase anidada.The custom class must not be a nested class. El "punto" adicional de la ruta de acceso de nombre completo hace que la división de espacio de nombres de clase sea ambigua e interfiere con otras características de XAML, como las propiedades adjuntas.The extra "dot" in the full-name path makes the class-namespace division ambiguous, and interferes with other XAML features such as attached properties. Si se puede crear una instancia de un objeto como un elemento de objeto, el objeto creado puede rellenar el formulario de elemento de propiedad de las propiedades que toman el objeto como su tipo subyacente.If an object can be instantiated as an object element, the created object can fill the property element form of any properties that take the object as their underlying type.

Todavía puede proporcionar valores de objeto para los tipos que no cumplen estos criterios, si habilita un convertidor de valores.You can still provide object values for types that do not meet these criteria, if you enable a value converter. Para obtener más información, vea convertidores de tipos y extensiones de marcado para XAML.For more information, see Type Converters and Markup Extensions for XAML.

EstructurasStructures

Las estructuras siempre se pueden construir en XAML, por definición de CLR.Structures are always able to be constructed in XAML, by CLR definition. Esto se debe a que un compilador CLR crea implícitamente un constructor sin parámetros para una estructura.This is because a CLR compiler implicitly creates a parameterless constructor for a structure. Este constructor inicializa todos los valores de propiedad a sus valores predeterminados.This constructor initializes all property values to their defaults.

En algunos casos, no es deseable el comportamiento de construcción predeterminado para una estructura.In some cases, the default construction behavior for a structure is not desirable. Esto puede deberse a que la estructura está pensada para rellenar los valores y funcionar conceptualmente como una Unión.This might be because the structure is intended to fill values and function conceptually as a union. Como Unión, los valores contenidos podrían tener interpretaciones mutuamente excluyentes y, por lo tanto, no se puede establecer ninguna de sus propiedades.As a union, the contained values might have mutually exclusive interpretations, and therefore, none of its properties are settable. Un ejemplo de este tipo de estructura en el vocabulario de WPF es GridLength .An example of such a structure in the WPF vocabulary is GridLength. Estas estructuras deben implementar un convertidor de tipos para que los valores se puedan expresar en forma de atributo, mediante el uso de convenciones de cadena que crean las diferentes interpretaciones o modos de los valores de la estructura.Such structures should implement a type converter so that the values can be expressed in attribute form, by using string conventions that create the different interpretations or modes of the structure values. La estructura también debe exponer un comportamiento similar para la construcción del código a través de un constructor sin parámetros.The structure should also expose similar behavior for code construction through a non-parameterless constructor.

InterfacesInterfaces

Las interfaces se pueden usar como tipos subyacentes de miembros.Interfaces can be used as underlying types of members. El sistema de tipos XAML comprueba la lista asignable y espera que el objeto que se proporciona como valor se pueda asignar a la interfaz.The XAML type system checks the assignable list and expects that the object that is provided as the value can be assigned to the interface. No hay ningún concepto de cómo se debe presentar la interfaz como un tipo XAML siempre que un tipo asignable pertinente admita los requisitos de construcción de XAML.There is no concept of how the interface must be presented as a XAML type as long as a relevant assignable type supports the XAML construction requirements.

Métodos de generadorFactory Methods

Los métodos de generador son una característica de XAML 2009.Factory methods are a XAML 2009 feature. Modifican el principio de XAML de que los objetos deben tener constructores sin parámetros.They modify the XAML principle that objects must have parameterless constructors. Los métodos de generador no se documentan en este artículo.Factory methods are not documented in this article. Consulte la Directiva x:FactoryMethod.See x:FactoryMethod Directive.

EnumeracionesEnumerations

Las enumeraciones tienen un comportamiento de conversión de tipo nativo XAML.Enumerations have XAML native type conversion behavior. Los nombres de constantes de enumeración especificados en XAML se resuelven con el tipo de enumeración subyacente y devuelven el valor de enumeración a un escritor de objetos XAML.Enumeration constant names specified in XAML are resolved against the underlying enumeration type, and return the enumeration value to a XAML object writer.

XAML admite el uso del estilo de marcas para las enumeraciones con FlagsAttribute aplicado.XAML supports a flags-style usage for enumerations with FlagsAttribute applied. Para obtener más información, consulte la Sintaxis de XAML en detalle.For more information, see XAML Syntax In Detail. (Lasintaxis XAML en detalle se escribe para la audiencia de WPF, pero la mayor parte de la información de ese tema es relevante para XAML que no es específico de un marco de implementación concreto).(XAML Syntax In Detail is written for the WPF audience, but most of the information in that topic is relevant for XAML that is not specific to a particular implementing framework.)

Definiciones de miembroMember Definitions

Los tipos pueden definir miembros para el uso de XAML.Types can define members for XAML usage. Es posible que los tipos definan miembros que se pueden usar en XAML incluso si ese tipo específico no se puede usar en XAML.It's possible for types to define members that are XAML-usable even if that specific type is not XAML-usable. Esto es posible debido a la herencia de CLR.This is possible because of CLR inheritance. Siempre que algún tipo que herede el miembro admita el uso de XAML como un tipo, y el miembro admita el uso de XAML para su tipo subyacente o tenga una sintaxis nativa de XAML disponible, ese miembro se puede usar en XAML.So long as some type that inherits the member supports XAML usage as a type, and the member supports XAML usage for its underlying type or has a native XAML syntax available, that member is XAML-usable.

PropiedadesProperties

Si define propiedades como una propiedad CLR pública mediante los get set patrones de descriptor de acceso y CLR típicos y las palabras clave apropiadas para el lenguaje, el sistema de tipos XAML puede informar de la propiedad como un miembro con la información adecuada proporcionada para XamlMember las propiedades, como IsReadPublic y IsWritePublic .If you define properties as a public CLR property using the typical CLR get and set accessor patterns and language-appropriate keywording, the XAML type system can report the property as a member with appropriate information provided for XamlMember properties, such as IsReadPublic and IsWritePublic.

Las propiedades específicas pueden habilitar una sintaxis de texto aplicando TypeConverterAttribute .Specific properties can enable a text syntax by applying TypeConverterAttribute. Para obtener más información, vea convertidores de tipos y extensiones de marcado para XAML.For more information, see Type Converters and Markup Extensions for XAML.

En ausencia de una sintaxis de texto o de una conversión XAML nativa y, en ausencia de más direccionamiento indirecto, como un uso de la extensión de marcado, el tipo de una propiedad ( TargetType en el sistema de tipos XAML) debe ser capaz de devolver una instancia a un escritor de objetos XAML tratando el tipo de destino como un tipo CLR.In the absence of a text syntax or native XAML conversion and in the absence of further indirection, such as a markup extension usage, the type of a property (TargetType in the XAML type system) must be able to return an instance to a XAML object writer by treating the target type as a CLR type.

Si se usa XAML 2009, se puede usar la extensión de marcado x:Reference para proporcionar valores si no se cumplen las consideraciones anteriores; sin embargo, eso es más un problema de uso que un problema de definición de tipo.If using XAML 2009, x:Reference Markup Extension can be used to provide values if the previous considerations are not met; however, that is more of a usage issue than a type definition issue.

EventosEvents

Si define eventos como un evento CLR público, el sistema de tipos XAML puede informar del evento como un miembro con IsEvent as true .If you define events as a public CLR event, the XAML type system can report the event as a member with IsEvent as true. El cableado de los controladores de eventos no está dentro del ámbito de las funciones de los servicios XAML de .NET; el cableado se deja en marcos e implementaciones específicos.Wiring the event handlers is not within the scope of .NET XAML Services capabilities; wiring is left to specific frameworks and implementations.

MétodosMethods

El código insertado para los métodos no es una funcionalidad XAML predeterminada.Inline code for methods is not a default XAML capability. En la mayoría de los casos, no se hace referencia directamente a los miembros de método desde XAML, y el rol de los métodos en XAML solo es proporcionar compatibilidad con patrones específicos de XAML.In most cases, you do not directly reference method members from XAML, and the role of methods in XAML is only to provide support for specific XAML patterns. la Directiva x:FactoryMethod es una excepción.x:FactoryMethod Directive is an exception.

CamposFields

Las instrucciones de diseño de CLR desaconsejan los campos no estáticos.CLR design guidelines discourage nonstatic fields. En el caso de los campos estáticos, solo puede acceder a los valores de campo estáticos a través de la extensión de marcado x:Static. en este caso, no está haciendo nada especial en la definición de CLR para exponer un campo para los usos de x:Static .For static fields, you can access static field values only through x:Static Markup Extension; in this case you are not doing anything special in the CLR definition to expose a field for x:Static usages.

Miembros que se van a adjuntarAttachable Members

Los miembros adjuntables se exponen a XAML a través de un patrón de método de descriptor de acceso en un tipo de definiciónAttachable members are exposed to XAML through an accessor method pattern on a defining type. No es necesario que el propio tipo de definición se pueda usar en XAML como un objeto.The defining type itself does not need to be XAML-usable as an object. De hecho, un patrón común es declarar una clase de servicio cuyo rol sea el propietario del miembro que se va a adjuntar e implementar los comportamientos relacionados, pero no atender ninguna otra función, como la representación de la interfaz de usuario.In fact, a common pattern is to declare a service class whose role is to own the attachable member and implement the related behaviors, but serve no other function such as a UI representation. En las secciones siguientes, el marcador de posición PropertyName representa el nombre del miembro que se va a adjuntar.For the following sections, the placeholder PropertyName represents the name of your attachable member. Ese nombre debe ser válido en la Gramática XamlName.That name must be valid in the XamlName Grammar.

Tenga cuidado con los conflictos de nombres entre estos patrones y otros métodos de un tipo.Be cautious of name collisions between these patterns and other methods of a type. Si existe un miembro que coincide con uno de los patrones, un procesador XAML puede interpretarlo como una ruta de uso de miembros que se puede adjuntar, aunque no sea su intención.If a member exists that matches one of the patterns, it can be interpreted as an attachable member usage pathway by a XAML processor even if that was not your intention.

El descriptor de acceso GetPropertyNameThe GetPropertyName Accessor

La firma para el GetPropertyName descriptor de acceso debe ser:The signature for the GetPropertyName accessor must be:

public static object GetPropertyName(object target)

  • El objeto target puede especificarse como un tipo más específico en la implementación.The target object can be specified as a more specific type in your implementation. Puede utilizar esto para limitar el uso del miembro que se puede adjuntar; los usos fuera del ámbito previsto producirán excepciones de conversión no válidas que se mostrarán después de un error de análisis de XAML.You can use this to scope the usage of your attachable member; usages outside your intended scope will throw invalid cast exceptions that are then surfaced by a XAML parse error. El nombre del parámetro target no es un requisito, pero se denomina target por Convención en la mayoría de las implementaciones.The parameter name target is not a requirement, but is named target by convention in most implementations.

  • El valor devuelto puede especificarse como un tipo más específico en la implementación.The return value can be specified as a more specific type in your implementation.

Para admitir una TypeConverter Sintaxis de texto habilitada para el uso de atributos del miembro adjuntable, aplique TypeConverterAttribute al GetPropertyName descriptor de acceso.To support a TypeConverter enabled text syntax for attribute usage of the attachable member, apply TypeConverterAttribute to the GetPropertyName accessor. La aplicación de a en get lugar de set puede parecer no intuitiva; sin embargo, esta Convención puede admitir el concepto de miembros que se pueden adjuntar de solo lectura que son serializables, lo que resulta útil en los escenarios del diseñador.Applying to the get instead of the set may seem non-intuitive; however, this convention can support the concept of read-only attachable members that are serializable, which is useful in designer scenarios.

El descriptor de acceso SetPropertyNameThe SetPropertyName Accessor

La firma para el SetPropertyName descriptor de acceso debe ser:The signature for the SetPropertyName accessor must be:

public static void SetPropertyName(object target, object value)

  • El target objeto se puede especificar como un tipo más específico en la implementación, con la misma lógica y las mismas consecuencias que se describen en la sección anterior.The target object can be specified as a more specific type in your implementation, with same logic and consequences as described in the previous section.

  • El objeto value puede especificarse como un tipo más específico en la implementación.The value object can be specified as a more specific type in your implementation.

Recuerde que el valor de este método es la entrada procedente del uso de XAML, normalmente en forma de atributo.Remember that the value for this method is the input coming from the XAML usage, typically in attribute form. En el formulario de atributo debe haber compatibilidad con el convertidor de valores para una sintaxis de texto y el atributo en el GetPropertyName descriptor de acceso s.From attribute form there must be value converter support for a text syntax, and you attribute on the GetPropertyNames accessor.

Almacenes de miembros adjuntablesAttachable Member Stores

Normalmente, los métodos de descriptor de acceso no son suficientes para proporcionar un medio para colocar los valores de miembro que se pueden asociar en un gráfico de objetos, o para recuperar los valores del gráfico de objetos y serializarlos correctamente.The accessor methods are typically not enough to provide a means to place attachable member values into an object graph, or to retrieve values out of the object graph and serialize them properly. Para proporcionar esta funcionalidad, los target objetos de las signaturas del descriptor de acceso anterior deben ser capaces de almacenar valores.To provide this functionality, the target objects in the previous accessor signatures must be capable of storing values. El mecanismo de almacenamiento debe ser coherente con el principio de miembro que se puede adjuntar que el miembro se puede asociar a los destinos en los que el miembro que se puede adjuntar no está en la lista de miembros.The storage mechanism should be consistent with the attachable member principle that the member is attachable to targets where the attachable member is not in the members list. Los servicios XAML de .NET proporcionan una técnica de implementación para los almacenes de miembros que se asocian a través de las API IAttachedPropertyStore y AttachablePropertyServices ..NET XAML Services provides an implementation technique for attachable member stores through the APIs IAttachedPropertyStore and AttachablePropertyServices. IAttachedPropertyStore los escritores de XAML utilizan para detectar la implementación del almacén y deben implementarse en el tipo que es target de los descriptores de acceso.IAttachedPropertyStore is used by the XAML writers to discover the store implementation, and should be implemented on the type that is the target of the accessors. Las API estáticas AttachablePropertyServices se utilizan dentro del cuerpo de los descriptores de acceso y hacen referencia al miembro que se puede adjuntar por su AttachableMemberIdentifier .The static AttachablePropertyServices APIs are used within the body of the accessors, and refer to the attachable member by its AttachableMemberIdentifier.

Es importante atribuir correctamente sus tipos, miembros y ensamblados para poder notificar información del sistema de tipos XAML a los servicios XAML de .NET.Correctly attributing your types, members, and assemblies is important in order to report XAML type system information to .NET XAML Services. La información del sistema de tipos XAML de informes es pertinente si se aplica alguna de las siguientes situaciones:Reporting XAML type system information is relevant if either of the following situations apply:

  • Piensa usar sus tipos con sistemas XAML que están directamente basados en los lectores XAML de los servicios XAML de .NET y los escritores de XAML.You intend your types for use with XAML systems that are directly based on .NET XAML Services XAML readers and XAML writers.
  • Se define o usa un marco de trabajo que usa XAML basado en esos lectores y escritores de XAML.You define or use a XAML-utilizing framework that's based on those XAML readers and XAML writers.

Para obtener una lista de cada atributo relacionado con XAML que es relevante para la compatibilidad con XAML de los tipos personalizados, vea atributos de CLR relacionados con XAML para tipos y bibliotecas personalizados.For a listing of each XAML-related attribute that's relevant for XAML support of your custom types, see XAML-Related CLR Attributes for Custom Types and Libraries.

UsoUsage

El uso de tipos personalizados requiere que el autor de marcado deba asignar un prefijo para el ensamblado y el espacio de nombres CLR que contienen el tipo personalizado.Usage of custom types requires that the markup author must map a prefix for the assembly and CLR namespace that contain the custom type. Este procedimiento no se documenta en este tema.This procedure is not documented in this topic.

Nivel de accesoAccess Level

XAML proporciona un medio para cargar y crear instancias de tipos que tienen un internal nivel de acceso.XAML provides a means to load and instantiate types that have an internal access level. Esta funcionalidad se proporciona para que el código de usuario pueda definir sus propios tipos y, a continuación, crear instancias de esas clases a partir del marcado que también forma parte del mismo ámbito de código de usuario.This capability is provided so that user code can define its own types, and then instantiate those classes from markup that is also part of the same user code scope.

Un ejemplo de WPF es cada vez que el código de usuario define un UserControl que está pensado como una manera de refactorizar un comportamiento de la interfaz de usuario, pero no como parte de cualquier mecanismo de extensión posible que podría estar implícito al declarar la clase auxiliar con el public nivel de acceso.An example from WPF is whenever user code defines a UserControl that is intended as a way to refactor a UI behavior, but not as part of any possible extension mechanism that might be implied by declaring the supporting class with public access level. Este tipo se UserControl puede declarar con internal acceso si el código de respaldo se compila en el mismo ensamblado desde el que se hace referencia a él como un tipo XAML.Such a UserControl can be declared with internal access if the backing code is compiled into the same assembly from which it is referenced as a XAML type.

En el caso de una aplicación que carga XAML con plena confianza y usa XamlObjectWriter , la carga de clases con el internal nivel de acceso siempre está habilitada.For an application that loads XAML under full trust and uses XamlObjectWriter, loading classes with internal access level is always enabled.

Para una aplicación que carga XAML en confianza parcial, puede controlar las características del nivel de acceso mediante la XamlAccessLevel API.For an application that loads XAML under partial trust, you can control the access level characteristics by using the XamlAccessLevel API. Además, los mecanismos de aplazamiento (como el sistema de plantilla de WPF) deben poder propagar los permisos de nivel de acceso y conservarlos para las evaluaciones de tiempo de ejecución eventuales; Esto se controla internamente pasando la XamlAccessLevel información.Also, deferral mechanisms (such as the WPF template system) must be able to propagate any access level permissions and preserve them for the eventual run time evaluations; this is handled internally by passing the XamlAccessLevel information.

Implementación de WPFWPF Implementation

XAML de WPF usa un modelo de acceso de confianza parcial en el que si BAML se carga bajo confianza parcial, el acceso está restringido a AssemblyAccessTo para el ensamblado que es el origen BAML.WPF XAML uses a partial-trust access model where if BAML is loaded under partial trust, access is restricted to AssemblyAccessTo for the assembly that is the BAML source. Para el aplazamiento, WPF usa IXamlObjectWriterFactory.GetParentSettings como mecanismo para pasar la información de nivel de acceso.For deferral, WPF uses IXamlObjectWriterFactory.GetParentSettings as a mechanism for passing the access level information.

En la terminología XAML de WPF, un tipo interno es un tipo definido por el mismo ensamblado que también incluye el XAML de referencia.In WPF XAML terminology, an internal type is a type that is defined by the same assembly that also includes the referencing XAML. Este tipo se puede asignar a través de un espacio de nombres XAML que omita deliberadamente la parte Assembly = de una asignación, por ejemplo, xmlns:local="clr-namespace:WPFApplication1" .Such a type can be mapped through a XAML namespace that deliberately omits the assembly= portion of a mapping, for example, xmlns:local="clr-namespace:WPFApplication1". Si BAML hace referencia a un tipo interno y ese tipo tiene internal nivel de acceso, genera una GeneratedInternalTypeHelper clase para el ensamblado.If BAML references an internal type and that type has internal access level, this generates a GeneratedInternalTypeHelper class for the assembly. Si desea evitar GeneratedInternalTypeHelper , debe usar public el nivel de acceso o debe factorizar la clase correspondiente en un ensamblado independiente y hacer que ese ensamblado dependa.If you want to avoid GeneratedInternalTypeHelper, you either must use public access level, or must factor the relevant class into a separate assembly and make that assembly dependent.

Vea tambiénSee also