Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este tema se definen los términos que se usan para describir los elementos de la sintaxis XAML. Estos términos se usan con frecuencia durante el resto de esta documentación, tanto para la documentación de WPF específicamente como para los otros marcos que usan XAML o los conceptos básicos de XAML habilitados por la compatibilidad del lenguaje XAML en el nivel System.Xaml. En este tema se expande la terminología básica introducida en el tema XAML en WPF.
Especificación del lenguaje XAML
La terminología de la sintaxis XAML que se define aquí también se define o se hace referencia en la especificación del lenguaje XAML. XAML es un lenguaje basado en XML y sigue o amplía las reglas estructurales XML. Parte de la terminología se comparte o se basa en la terminología que se usa habitualmente al describir el lenguaje XML o el modelo de objetos de documento XML.
Para obtener más información sobre la especificación del lenguaje XAML, descargue [MS-XAML] desde el Centro de descarga de Microsoft.
XAML y CLR
XAML es un lenguaje de marcado. Common Language Runtime (CLR), como se indica en su nombre, permite la ejecución en tiempo de ejecución. XAML no es por sí mismo uno de los lenguajes comunes que el entorno de ejecución de CLR consume directamente. En cambio, puedes pensar en XAML como soportando su propio sistema de tipos. El sistema de análisis XAML específico que utiliza WPF se basa en el CLR y en el sistema de tipos del CLR. Los tipos XAML se asignan a tipos CLR para instanciar una representación en tiempo de ejecución cuando se compila el XAML para WPF. Por este motivo, el resto de la explicación de la sintaxis de este documento incluirá referencias al sistema de tipos CLR, aunque las discusiones de sintaxis equivalentes en la especificación del lenguaje XAML no lo hagan. (Según el nivel de especificación del lenguaje XAML, los tipos XAML se podrían asignar a cualquier otro sistema de tipos, que no tiene que ser CLR, pero eso requeriría la creación y el uso de un analizador XAML diferente).
Miembros de tipos y herencia de clase
Las propiedades y eventos tal como aparecen como miembros XAML de un tipo WPF a menudo son heredados de tipos base. Por ejemplo, considere este ejemplo: <Button Background="Blue" .../>
. La Background propiedad no es una propiedad declarada directamente en la Button clase, si se examina la definición de clase, los resultados de la reflexión o la documentación. En su lugar, Background se hereda de la clase base Control .
El comportamiento de herencia de clases de los elementos XAML de WPF es una desviación significativa de una interpretación dictada por esquemas del marcado XML. La herencia de clases puede ser compleja, especialmente cuando las clases base intermedias son abstractas o cuando las interfaces están implicadas. Este es uno de los motivos por los que es difícil representar con precisión y en su totalidad el conjunto de elementos XAML y sus atributos permitidos utilizando los tipos de esquema que normalmente se emplean para la programación XML, como el formato DTD o XSD. Otra razón es que las características de extensibilidad y asignación de tipos del propio lenguaje XAML impiden la integridad de cualquier representación fija de los tipos y miembros permitidos.
Sintaxis del elemento Object
La sintaxis del elemento Object es la sintaxis de marcado XAML que crea instancias de una clase o estructura CLR declarando un elemento XML. Esta sintaxis es similar a la sintaxis de elemento de otros lenguajes de marcado, como HTML. La sintaxis del elemento object comienza con un paréntesis angular izquierdo (<), seguido inmediatamente del nombre de tipo de la clase o estructura que está siendo instanciada. Cero o más espacios pueden seguir al nombre del tipo y también se pueden declarar cero o más atributos en el elemento objeto, separando cada par de nombre de atributo="valor" con uno o más espacios. Por último, uno de los siguientes debe ser verdadero:
El elemento y la etiqueta deben cerrarse mediante una barra diagonal (/) seguida inmediatamente de un corchete angular derecho (>).
La etiqueta de apertura debe completarse con un corchete angular derecho (>). Otros elementos de objeto, elementos de propiedad o texto interno pueden seguir la etiqueta de apertura. Exactamente qué contenido puede estar contenido aquí suele estar restringido por el modelo de objetos del elemento. La etiqueta de cierre equivalente para el elemento de objeto debe existir también, y estar correctamente anidada y equilibrada con otros pares de etiquetas de apertura y cierre.
XAML tal como lo implementa .NET tiene un conjunto de reglas que asignan elementos de objeto a tipos, atributos en propiedades o eventos y espacios de nombres XAML a espacios de nombres CLR más ensamblados. Para WPF y .NET, los elementos de objeto XAML se asignan a tipos de .NET tal como se definen en ensamblados a los que se hace referencia y los atributos se asignan a los miembros de esos tipos. Cuando haces referencia a un tipo CLR en XAML, también tienes acceso a los miembros heredados de ese tipo.
Por ejemplo, el siguiente ejemplo muestra la sintaxis de un elemento de objeto que crea una nueva instancia de la clase Button y también especifica un atributo Name y un valor para ese atributo.
<Button Name="CheckoutButton"/>
El ejemplo siguiente es la sintaxis del elemento de objeto que también incluye la sintaxis de la propiedad de contenido XAML. El texto interno contenido en se usará para establecer la TextBox propiedad de contenido XAML, Text.
<TextBox>This is a Text Box</TextBox>
Modelos de contenido
Una clase podría admitir un uso como elemento de objeto XAML en términos de sintaxis, pero ese elemento solo funcionará correctamente en una aplicación o página cuando se coloque en una posición esperada de un modelo de contenido global o árbol de elementos. Por ejemplo, un MenuItem objeto normalmente solo debe colocarse como elemento secundario de una MenuBase clase derivada, como Menu. Los modelos de contenido para elementos específicos se documentan como parte de las anotaciones en las páginas de las clases para controles y otras clases de WPF que se pueden utilizar como elementos XAML.
Propiedades de los elementos de objeto
Las propiedades en XAML se establecen mediante una variedad de sintaxis posibles. La sintaxis que se puede usar para una propiedad determinada variará, en función de las características del sistema de tipos subyacentes de la propiedad que está estableciendo.
Al establecer valores de propiedades, se agregan características o características a objetos a medida que existen en el gráfico de objetos en tiempo de ejecución. El estado inicial del objeto creado a partir de un elemento de objeto se basa en el comportamiento del constructor sin parámetros. Normalmente, la aplicación usará algo distinto de una instancia completamente predeterminada de cualquier objeto determinado.
Sintaxis de atributo (propiedades)
La sintaxis de atributo es la sintaxis de marcado XAML que establece un valor para una propiedad declarando un atributo en un elemento de objeto existente. El nombre del atributo debe coincidir con el nombre del miembro CLR de la propiedad de la clase que respalda el elemento de objeto correspondiente. El nombre del atributo va seguido de un operador de asignación (=). El valor del atributo debe ser una cadena entre comillas.
Nota:
Puede usar comillas alternas para colocar una comilla literal dentro de un atributo. Por ejemplo, puede usar comillas simples como forma de declarar una cadena que contenga un carácter de comilla doble dentro de ella. Tanto si usa comillas simples como dobles, debe usar un par coincidente para abrir y cerrar la cadena de valor de atributo. También hay secuencias de escape u otras técnicas disponibles para trabajar en torno a las restricciones de caracteres impuestas por cualquier sintaxis XAML determinada. Consulta Entidades de caracteres XML y XAML.
Para establecerse a través de la sintaxis de atributo, una propiedad debe ser pública y debe ser escribible. El valor de la propiedad en el sistema de tipos de respaldo debe ser un tipo de valor, o debe ser un tipo de referencia que pueda ser instanciado o referenciado por un procesador de XAML al acceder al tipo de respaldo correspondiente.
Para los eventos XAML de WPF, el evento al que se hace referencia como nombre de atributo debe ser público y tener un delegado público.
La propiedad o evento debe ser un miembro de la clase o estructura que es instanciada por el elemento de objeto contenedor.
Procesamiento de valores de atributo
Un procesador XAML procesa el valor de cadena que contiene las comillas de apertura y cierre. En el caso de las propiedades, el comportamiento de procesamiento predeterminado viene determinado por el tipo de la propiedad CLR subyacente.
El valor del atributo se rellena mediante uno de los siguientes, mediante este orden de procesamiento:
Si el procesador XAML encuentra una llave o un elemento de objeto que deriva de MarkupExtension, la extensión de marcado a la que se hace referencia se evalúa primero en lugar de procesar el valor como una cadena y el objeto devuelto por la extensión de marcado se usa como valor. En muchos casos, el objeto devuelto por una extensión de marcado será una referencia a un objeto existente o una expresión que aplaza la evaluación hasta el tiempo de ejecución y no es un objeto recién creado.
Si la propiedad se declara con un atributo TypeConvertero el tipo de valor de esa propiedad se declara con un atributo TypeConverter, el valor de cadena del atributo se envía al convertidor de tipos como entrada de conversión y el convertidor devolverá una nueva instancia de objeto.
Si no hay TypeConverter, se intenta convertir directamente al tipo de propiedad. Este nivel final es una conversión directa en el valor nativo del analizador entre los tipos primitivos del lenguaje XAML o una comprobación de los nombres de las constantes nombradas en una enumeración (el analizador obtiene acceso a los valores coincidentes).
Valores de atributo de enumeración
Los analizadores XAML procesan las enumeraciones intrínsecamente y los miembros de una enumeración deben especificarse especificando el nombre de cadena de una de las constantes con nombre de la enumeración.
En el caso de los valores de enumeración sin marca, el comportamiento nativo consiste en procesar la cadena de un valor de atributo y resolverlo en uno de los valores de enumeración. No se especifica la enumeración en el formato Enumeración.Valor, como se hace en el código. En su lugar, solo se especifica Value y Enumeration se deduce por el tipo de propiedad que estás configurando. Si especifica un atributo en la forma Enumeración.Valor, no se resolverá correctamente.
En el caso de las enumeraciones de tipo bandera, el comportamiento se basa en el método Enum.Parse. Puede especificar varios valores para una enumeración flagwise separando cada valor con una coma. Sin embargo, no se pueden combinar valores de enumeración que no sean tipo bandera. Por ejemplo, no puede usar la sintaxis de comas para intentar crear un objeto Trigger que actúe sobre múltiples condiciones de una enumeración sin banderas.
<!--This will not compile, because Visibility is not a flagwise enumeration.-->
...
<Trigger Property="Visibility" Value="Collapsed,Hidden">
<Setter ... />
</Trigger>
...
Las enumeraciones con marcas que admiten atributos que se pueden establecer en XAML son poco frecuentes en WPF. Sin embargo, una de estas enumeraciones es StyleSimulations. Por ejemplo, podría usar la sintaxis de atributo flagwise delimitada por comas para modificar el ejemplo proporcionado en los comentarios de la Glyphs clase ; StyleSimulations = "BoldSimulation"
podría convertirse en StyleSimulations = "BoldSimulation,ItalicSimulation"
.
KeyBinding.Modifiers es otra propiedad donde se puede especificar más de un valor de enumeración. Sin embargo, esta propiedad puede ser un caso especial, ya que la ModifierKeys enumeración admite su propio convertidor de tipos. El convertidor de tipos para modificadores usa un signo más (+) como delimitador en lugar de una coma (,). Esta conversión admite la sintaxis más tradicional para representar combinaciones de teclas en la programación de Microsoft Windows, como "Ctrl+Alt".
Propiedades y referencias de nombre de miembro de evento
Al especificar un atributo, puede hacer referencia a cualquier propiedad o evento que exista como miembro del tipo CLR que creó para el elemento de objeto contenedor.
O bien, puede hacer referencia a una propiedad adjunta o un evento adjunto, independientemente del elemento de objeto contenedor. (Las propiedades adjuntas se describen en una sección próxima).
También puede asignar un nombre a cualquier evento de cualquier objeto al que se pueda acceder a través del espacio de nombres predeterminado mediante un nombre parcialmente calificado de typeName.evento; esta sintaxis admite la asociación de controladores para eventos enrutados donde el controlador tiene como objetivo gestionar el enrutamiento de eventos desde elementos secundarios, pero el elemento primario no tiene ese evento en su tabla de miembros. Esta sintaxis es similar a una sintaxis de evento adjunta, pero el evento aquí no es un evento adjunto verdadero. En su lugar, hace referencia a un evento con un nombre calificado. Para obtener más información, consulte Información general sobre eventos enrutados.
En algunos escenarios, los nombres de propiedad a veces se proporcionan como el valor de un atributo, en lugar del nombre del atributo. Ese nombre de propiedad también puede incluir calificadores, como la propiedad especificada en la forma ownerType y dependencyPropertyName. Este escenario es común al escribir estilos o plantillas en XAML. Las reglas de procesamiento de los nombres de propiedad proporcionados como un valor de atributo son diferentes y se rigen por el tipo de la propiedad que se establece o por los comportamientos de determinados subsistemas de WPF. Para obtener más información, consulte Aplicación de estilos y plantillas.
Otro uso de los nombres de propiedad es cuando un valor de atributo describe una relación de propiedad-propiedad. Esta característica se usa para el enlace de datos y para destinos de guion gráfico, y está habilitada por la PropertyPath clase y su convertidor de tipos. Para obtener una descripción más completa de la semántica de búsqueda, consulta Sintaxis XAML de PropertyPath.
Sintaxis del elemento Property
La sintaxis del elemento property es una sintaxis que difiere algo de las reglas de sintaxis XML básicas para los elementos. En XML, el valor de un atributo es una cadena de facto, con la única variación posible que es el formato de codificación de cadenas que se está usando. En XAML, puedes asignar otros elementos de objeto para que sean el valor de una propiedad. Esta funcionalidad está habilitada por la sintaxis del elemento de propiedad. En lugar de especificar la propiedad como un atributo dentro de la etiqueta del elemento, la propiedad se especifica mediante una etiqueta de apertura del elemento en la forma elementTypeName.propertyName. El valor de la propiedad se especifica dentro de esta etiqueta, y luego se cierra el elemento de propiedad.
En concreto, la sintaxis comienza con un corchete angular izquierdo (<), seguido inmediatamente por el nombre de tipo de la clase o estructura dentro de la sintaxis del elemento de propiedad. Esto va seguido inmediatamente de un único punto (.), a continuación, por el nombre de una propiedad y, a continuación, por un corchete angular derecho (>). Al igual que con la sintaxis de atributo, esa propiedad debe existir dentro de los miembros públicos declarados del tipo especificado. El valor que se va a asignar a la propiedad está incluido en el elemento property. Normalmente, el valor se da como uno o varios elementos de objeto, ya que especificar objetos como valores es el escenario en el que la sintaxis del elemento de propiedad está pensada para abordar. Por último, se debe proporcionar una etiqueta de cierre equivalente que especifique la combinación elementTypeName.propertyName, en el anidamiento y equilibrio adecuados con otras etiquetas de elemento.
Por ejemplo, la siguiente es la sintaxis de elemento de la propiedad ContextMenu de un Button.
<Button>
<Button.ContextMenu>
<ContextMenu>
<MenuItem Header="1">First item</MenuItem>
<MenuItem Header="2">Second item</MenuItem>
</ContextMenu>
</Button.ContextMenu>
Right-click me!</Button>
El valor de un elemento de propiedad también se puede proporcionar como texto interno, en los casos en los que el tipo de propiedad que se especifica es un tipo de valor primitivo, como String, o una enumeración donde se especifica un nombre. Estos dos usos son algo poco comunes, ya que cada uno de estos casos también podría usar una sintaxis de atributo más simple. Un escenario para rellenar un elemento de propiedad con una cadena es cuando las propiedades no son propiedad de contenido XAML, pero aún se utilizan para representar texto de la interfaz de usuario, y se requieren elementos específicos de espacio en blanco, como saltos de línea, para que aparezcan en dicho texto. La sintaxis de atributos no puede mantener los saltos de línea, pero la sintaxis de elementos de propiedad sí puede hacerlo, siempre que esté activa la preservación significativa del espacio en blanco (para obtener más detalles, consulte Procesamiento de espacios en blanco en XAML). Otro escenario es para que la directiva x:Uid se pueda aplicar al elemento de propiedad y, por tanto, marcar el valor dentro como un valor que se debe localizar en la salida de WPF en el BAML o por otras técnicas.
Un elemento de propiedad no se representa en el árbol lógico de WPF. Un elemento de propiedad es simplemente una sintaxis determinada para establecer una propiedad y no es un elemento que tiene una instancia o un objeto de respaldo. (Para obtener más información sobre el concepto de árbol lógico, vea Árboles en WPF).
En el caso de las propiedades en las que se admite la sintaxis de atributos y elementos de propiedad, las dos sintaxis suelen tener el mismo resultado, aunque las sutilezas como el control de espacios en blanco pueden variar ligeramente entre las sintaxis.
Sintaxis de colección
La especificación XAML requiere implementaciones de procesador XAML para identificar las propiedades en las que el tipo de valor es una colección. La implementación general del procesador XAML en .NET se basa en código administrado y CLR, e identifica los tipos de colección a través de uno de los siguientes:
El tipo implementa IList.
El tipo implementa IDictionary.
El tipo se deriva de Array (para obtener más información sobre las matrices en XAML, consulta x:Array Markup Extension).)
Si el tipo de una propiedad es una colección, no es necesario especificar el tipo de colección inferido en el marcado como un elemento de objeto. En su lugar, los elementos destinados a convertirse en elementos de la colección se especifican como uno o varios elementos secundarios del elemento de propiedad. Cada elemento de este tipo se evalúa como un objeto durante la carga y se agrega a la colección llamando al Add
método de la colección implícita. Por ejemplo, la Triggers propiedad de Style toma el tipo especializado de colección TriggerCollection, que implementa IList. No es necesario crear una instancia de un elemento de objeto TriggerCollection en el marcado. En su lugar, se especifican uno o varios Trigger elementos como elementos dentro del Style.Triggers
elemento de propiedad, donde Trigger (o una clase derivada) es el tipo esperado como tipo de elemento para el fuertemente tipado e implícito TriggerCollection.
<Style x:Key="SpecialButton" TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="Button.IsMouseOver" Value="true">
<Setter Property = "Background" Value="Red"/>
</Trigger>
<Trigger Property="Button.IsPressed" Value="true">
<Setter Property = "Foreground" Value="Green"/>
</Trigger>
</Style.Triggers>
</Style>
Una propiedad puede ser un tipo de colección y la propiedad de contenido XAML para ese tipo y tipos derivados, que se describen en la sección siguiente de este tema.
Un elemento de colección implícito crea un miembro en la representación del árbol lógico, aunque no aparezca en el marcado como un elemento. Normalmente, el constructor del tipo padre efectúa la instanciación de la colección que es una de sus propiedades, y la colección inicialmente vacía se convierte en parte del árbol de objetos.
Nota:
Las interfaces genéricas de lista y diccionario (IList<T> y IDictionary<TKey,TValue>) no se admiten para la detección de colecciones. Sin embargo, puede usar la List<T> clase como una clase base, ya que implementa IList directamente o Dictionary<TKey,TValue> como una clase base, ya que implementa IDictionary directamente.
En las páginas de referencia de .NET para tipos de colección, esta sintaxis, que omite deliberadamente el elemento de objeto para una colección, se menciona ocasionalmente en las secciones de sintaxis de XAML como Sintaxis de Colección Implícita.
Con la excepción del elemento raíz, cada elemento de objeto de un archivo XAML anidado como elemento secundario de otro elemento es realmente un elemento que es uno o ambos de los casos siguientes: un miembro de una propiedad de colección implícita de su elemento primario o un elemento que especifica el valor de la propiedad de contenido XAML para el elemento primario (las propiedades de contenido XAML se tratarán en una sección próxima). En otras palabras, la relación entre los elementos padre e hijos en una página de marcado es esencialmente un único objeto raíz, y cada elemento objeto situado debajo de la raíz es una instancia única que proporciona un valor de propiedad del padre o uno de los elementos dentro de una colección que también es un valor de propiedad de tipo colección del padre. Este concepto de raíz única es común con XML y se refuerza con frecuencia en el comportamiento de las API que cargan XAML como Load.
El ejemplo siguiente es una sintaxis que contiene el elemento object de una colección (GradientStopCollection) especificado explícitamente.
<LinearGradientBrush>
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Offset="0.0" Color="Red" />
<GradientStop Offset="1.0" Color="Blue" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
Tenga en cuenta que no siempre es posible declarar explícitamente la colección. Por ejemplo, al intentar declarar TriggerCollection explícitamente en el ejemplo mostrado Triggers anteriormente se produciría un error. Declarar explícitamente la colección requiere que la clase de colección admita un constructor sin parámetros y TriggerCollection no tenga un constructor sin parámetros.
Propiedades de contenido XAML
La sintaxis de contenido XAML es una sintaxis que solo está habilitada en las clases que incluyen ContentPropertyAttribute como parte de su declaración de clase. El ContentPropertyAttribute se refiere al nombre de la propiedad que es la propiedad de contenido para ese tipo de elemento (incluidas las clases derivadas). Cuando un procesador XAML lo procesa, los elementos secundarios o el texto interno que se encuentran entre las etiquetas de apertura y cierre del elemento de objeto se asignarán para que sean el valor de la propiedad de contenido XAML para ese objeto. Puede especificar elementos de propiedad explícitos para la propiedad de contenido, pero este uso no se muestra generalmente en las secciones de sintaxis XAML de la referencia de .NET. La técnica explícita o detallada tiene un valor ocasional para la claridad del marcado o como cuestión de estilo de marcado, pero normalmente la intención de una propiedad de contenido es simplificar el marcado para que los elementos que estén intuitivamente relacionados como elementos primarios y secundarios se puedan anidar directamente. Las etiquetas de elemento de propiedad para otras propiedades de un elemento no se asignan como "contenido" por una definición estricta del lenguaje XAML; se procesan anteriormente en el orden de procesamiento del analizador XAML y no se consideran "contenido".
Los valores de propiedad de contenido XAML deben ser contiguos
El valor de una propiedad de contenido XAML debe proporcionarse completamente antes o completamente después de cualquier otro elemento de propiedad en ese elemento de objeto. Esto es true si el valor de una propiedad de contenido XAML se especifica como una cadena o como uno o varios objetos. Por ejemplo, el código siguiente no se analiza.
<Button>I am a
<Button.Background>Blue</Button.Background>
blue button</Button>
Esto es ilegal esencialmente porque si esta sintaxis se hiciera explícita mediante la sintaxis de elemento de propiedad para el contenido, la propiedad de contenido se definiría dos veces.
<Button>
<Button.Content>I am a </Button.Content>
<Button.Background>Blue</Button.Background>
<Button.Content> blue button</Button.Content>
</Button>
Un ejemplo igualmente no válido es si la propiedad de contenido es una colección y los elementos secundarios se intercalan con elementos de propiedad:
<StackPanel>
<Button>This example</Button>
<StackPanel.Resources>
<SolidColorBrush x:Key="BlueBrush" Color="Blue"/>
</StackPanel.Resources>
<Button>... is illegal XAML</Button>
</StackPanel>
Propiedades de contenido y sintaxis de colección combinadas
Para aceptar más de un solo elemento de objeto como contenido, el tipo de la propiedad content debe ser específicamente un tipo de colección. De forma similar a la sintaxis de elementos de propiedad para los tipos de colección, un procesador XAML debe identificar los tipos que son tipos de colección. Si un elemento tiene una propiedad de contenido XAML y el tipo de la propiedad de contenido XAML es una colección, no es necesario especificar el tipo de colección implícito en el marcado como un elemento de objeto y no es necesario especificar la propiedad de contenido XAML como elemento de propiedad. Por lo tanto, el modelo de contenido aparente en el marcado ahora puede tener más de un elemento secundario asignado como contenido. A continuación se muestra la sintaxis de contenido de una Panel clase derivada. Todas las Panel clases derivadas establecen la propiedad de contenido XAML como Children, que requiere un valor de tipo UIElementCollection.
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<StackPanel>
<Button>Button 1</Button>
<Button>Button 2</Button>
<Button>Button 3</Button>
</StackPanel>
</Page>
Tenga en cuenta que ni el elemento de propiedad para Children ni el elemento para UIElementCollection son necesarios en el marcado. Se trata de una característica de diseño de XAML para que los elementos contenidos recursivamente que definen una interfaz de usuario se representen de forma más intuitiva como un árbol de elementos anidados con relaciones inmediatas de elementos primarios y secundarios, sin intervención de etiquetas de elemento de propiedad o objetos de colección. De hecho, UIElementCollection no se puede especificar explícitamente en el marcado como un elemento de objeto, por diseño. Dado que su único uso previsto es como una colección implícita, UIElementCollection no expone un constructor público sin parámetros y, por tanto, no se puede crear una instancia como un elemento de objeto.
Mezcla de elementos de propiedad y elementos de objeto dentro de un objeto que tiene una propiedad Content
La especificación XAML declara que un procesador XAML puede exigir que los elementos de objeto que se usan para rellenar la propiedad de contenido XAML dentro de un elemento de objeto deben ser contiguos y no deben mezclarse. Esta restricción contra la combinación de elementos de propiedad y contenido es aplicada por los procesadores XAML de WPF.
Puede tener un elemento de objeto secundario como el primer marcado inmediato dentro de un elemento de objeto. A continuación, puede introducir elementos de propiedad. O bien, puede especificar uno o varios elementos de propiedad, después contenido y más elementos de propiedad. Pero una vez que un elemento de propiedad sigue el contenido, no puede introducir ningún contenido adicional, solo puede agregar elementos de propiedad.
Este requisito de orden de elementos content/property no se aplica al texto interno usado como contenido. Sin embargo, sigue siendo un buen estilo de marcado para mantener el texto interno contiguo, ya que el espacio en blanco significativo será difícil de detectar visualmente en el marcado si los elementos de propiedad se intercalan con texto interno.
Espacios de nombres XAML
Ninguno de los ejemplos de sintaxis anteriores especificó un espacio de nombres XAML distinto del espacio de nombres XAML predeterminado. En las aplicaciones típicas de WPF, se especifica el espacio de nombres XAML predeterminado para que sea el espacio de nombres WPF. Puedes especificar espacios de nombres XAML distintos del espacio de nombres XAML predeterminado y seguir usando una sintaxis similar. Sin embargo, en cualquier lugar donde se llame a una clase que no sea accesible en el espacio de nombres XAML predeterminado, ese nombre de clase debe ir precedido del prefijo del espacio de nombres XAML como asignado al espacio de nombres CLR correspondiente. Por ejemplo, <custom:Example/>
es la sintaxis del elemento de objeto para crear instancias de una instancia de la Example
clase, donde el espacio de nombres CLR que contiene esa clase (y posiblemente la información del ensamblado externo que contiene tipos de respaldo) se asignó previamente al custom
prefijo.
Para obtener más información sobre los espacios de nombres XAML, consulta Espacios de nombres XAML y Asignación de espacios de nombres para XAML de WPF.
Extensiones de marcado
XAML define una entidad de programación de extensión de marcado que permite un escape del control normal del procesador XAML de valores de atributo de cadena o elementos de objeto y aplaza el procesamiento a una clase de respaldo. El carácter que identifica una extensión de marcado a un procesador XAML cuando se usa la sintaxis de atributo es la llave de apertura ({), seguida de cualquier carácter que no sea una llave de cierre (}). La primera cadena que sigue a la llave de apertura debe hacer referencia a la clase que proporciona el comportamiento de extensión determinado, donde la referencia puede omitir la subcadena "Extensión" si esa subcadena forma parte del nombre de clase true. Después, puede aparecer un solo espacio y, a continuación, cada carácter sucesivo se usa como entrada por la implementación de la extensión, hasta que se encuentre la llave de cierre.
La implementación xaml de .NET usa la MarkupExtension clase abstracta como base para todas las extensiones de marcado admitidas por WPF, así como otros marcos o tecnologías. Las extensiones de marcado que WPF implementan específicamente suelen proporcionar un medio para hacer referencia a otros objetos existentes o para hacer referencias diferidas a objetos que se evaluarán en tiempo de ejecución. Por ejemplo, una vinculación de datos simple de WPF se logra usando la extensión de marcado {Binding}
en lugar del valor que normalmente tomaría una propiedad determinada. Muchas de las extensiones de marcado de WPF habilitan una sintaxis de atributo para las propiedades donde de otra manera no sería posible. Por ejemplo, un Style objeto es un tipo relativamente complejo que contiene una serie anidada de objetos y propiedades. Los estilos de WPF se definen normalmente como un recurso en un ResourceDictionary, y a continuación, se hace referencia a ellos a través de una de las dos extensiones de marcado WPF que solicitan un recurso. La extensión de marcado aplaza la evaluación del valor de propiedad en una búsqueda de recursos y permite proporcionar el valor de la Style propiedad, tomando el tipo Style, en la sintaxis de atributo como en el ejemplo siguiente:
<Button Style="{StaticResource MyStyle}">My button</Button>
Aquí, StaticResource
identifica la StaticResourceExtension clase que proporciona la implementación de la extensión de marcado. La cadena siguiente MyStyle
se usa como entrada para el constructor no predeterminado StaticResourceExtension , donde el parámetro tal como se toma de la cadena de extensión declara el objeto solicitado ResourceKey.
MyStyle
se espera que sea el valor x:Key de un Style objeto definido como un recurso. El uso de la extensión de marcado StaticResource solicita que el recurso se utilice para proporcionar el valor de la propiedad Style mediante la lógica de búsqueda de recursos estáticos en tiempo de carga.
Para obtener más información sobre las extensiones de marcado, consulta Extensiones de marcado y XAML de WPF. Para obtener una referencia de las extensiones de marcado y otras características de programación XAML habilitadas en la implementación general de XAML de .NET, consulta Características del lenguaje espacio de nombres XAML (x:). Para las extensiones de marcado específicas de WPF, consulta Extensiones XAML de WPF.
Propiedades adjuntas
Las propiedades adjuntas son un concepto de programación introducido en XAML por el que las propiedades pueden ser propiedad y definidas por un tipo determinado, pero se establecen como atributos o elementos de propiedad en cualquier elemento. El escenario principal para el que están diseñadas las propiedades adjuntas consiste en permitir que los elementos secundarios de una estructura de marcado informen de información a un elemento primario sin necesidad de un modelo de objetos ampliamente compartido en todos los elementos. Por el contrario, los elementos primarios pueden usar las propiedades adjuntas para notificar información a los elementos secundarios. Para obtener más información sobre el propósito de las propiedades adjuntas y cómo crear sus propias propiedades adjuntas, vea Información general sobre las propiedades adjuntas.
Las propiedades adjuntas usan una sintaxis que superficialmente se asemeja a la sintaxis del elemento de propiedad, en el que también se especifica una combinación typeName.propertyName. Hay dos diferencias importantes:
Puede usar la combinación typeName.propertyName incluso cuando configure una propiedad adjunta mediante la sintaxis de atributo. Las propiedades adjuntas son el único caso en el que especificar el nombre de la propiedad es un requisito en una sintaxis de atributos.
También puede usar la sintaxis de elementos de propiedad para las propiedades adjuntadas. Sin embargo, para la sintaxis típica del elemento de propiedad, typeName que especifique es el elemento de objeto que contiene el elemento de propiedad. Si hace referencia a una propiedad adjunta, typeName es la clase que define la propiedad adjunta, no el elemento de objeto contenedor.
Eventos adjuntos
Los eventos adjuntos son otro concepto de programación introducido en XAML, donde los eventos se pueden definir mediante un tipo específico, pero los controladores se pueden adjuntar a cualquier elemento de objeto. En la implementación de WOF, a menudo el tipo que define un evento adjunto es un tipo estático que define un servicio y, a veces, esos eventos adjuntos se exponen mediante un alias de evento enrutado en tipos que exponen el servicio. Los controladores para eventos adjuntos se especifican mediante la sintaxis de atributo. Al igual que con los eventos adjuntos, la sintaxis del atributo se expande para los eventos adjuntos para permitir un typeName. uso de eventName , donde typeName es la clase que proporciona Add
descriptores de acceso del controlador de eventos y Remove
para la infraestructura de eventos adjunta, y eventName es el nombre del evento.
Anatomía de un elemento raíz XAML
En la tabla siguiente se muestra un elemento raíz XAML típico desglosado, en el que se muestran los atributos específicos de un elemento raíz:
Atributo | Descripción |
---|---|
<Page |
Apertura del elemento objeto del elemento raíz |
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
Espacio de nombres XAML predeterminado (WPF) |
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
Espacio de nombres XAML del lenguaje XAML |
x:Class="ExampleNamespace.ExampleCode" |
Declaración de clase parcial que conecta el marcado a cualquier código subyacente definido para la clase parcial. |
> |
Fin del elemento de objeto para la raíz. El objeto aún no está cerrado porque el elemento contiene elementos secundarios |
Usos XAML opcionales y no recomendados
En las secciones siguientes se describen los usos de XAML que son técnicamente compatibles con los procesadores XAML, pero que producen verborrea u otros problemas estéticos que interfieren con que los archivos XAML sigan siendo legibles cuando se desarrollan aplicaciones que contienen fuentes XAML.
Usos de elementos de propiedad opcionales
Los usos de elementos de propiedad opcionales incluyen escribir explícitamente propiedades de contenido de elementos que el procesador XAML considera implícitas. Por ejemplo, cuando declaras el contenido de un Menu, puedes optar por declarar explícitamente la colección Items del Menu como un elemento de etiqueta de propiedad <Menu.Items>
, y colocar cada MenuItem dentro de <Menu.Items>
, en lugar de usar el comportamiento implícito del procesador XAML que todos los elementos secundarios de un Menu deben ser MenuItem y se colocan en la colección Items. A veces, los usos opcionales pueden ayudar a aclarar visualmente la estructura de objetos tal como se representa en el marcado. O a veces, un uso explícito de elementos de propiedad puede evitar el marcado que es técnicamente funcional, pero visualmente confuso, como extensiones de marcado anidadas dentro de un valor de atributo.
Atributos completos typeName.memberName Qualified
TypeName. El formulario memberName de un atributo funciona de forma más universal que solo el caso de evento enrutado. Pero en otras situaciones, esa forma es superflua y deberías evitarla, aunque solo sea por razones de estilo de marcado y legibilidad. En el ejemplo siguiente, cada una de las tres referencias al Background atributo es completamente equivalente:
<Button Background="Blue">Background</Button>
<Button Button.Background="Blue">Button.Background</Button>
<Button Control.Background="Blue">Control.Background</Button>
Button.Background
funciona porque la búsqueda completa de esa propiedad en Button es correcta (Background se heredó de Control) y Button es la clase del elemento de objeto o una clase base.
Control.Background
funciona porque la Control clase define Background realmente y Control es una Button clase base.
Sin embargo, el siguiente ejemplo de formulario typeName.memberName no funciona y, por tanto, se muestra como comentario:
<!--<Button Label.Background="Blue">Does not work</Button> -->
Label es otra clase derivada de Control, y si hubiera especificado Label.Background
dentro de un elemento de objeto Label, este uso habría funcionado. Sin embargo, dado que Label no es la clase o clase base de Button, el comportamiento del procesador XAML especificado es procesar Label.Background
como propiedad adjunta.
Label.Background
no es una propiedad adjunta disponible y se produce un error en este uso.
Elementos de la propiedad baseTypeName.memberName
De forma análoga a cómo la sintaxis typeName.memberName funciona para la sintaxis de atributo, una sintaxis baseTypeName.memberName funciona para la sintaxis del elemento de propiedad. Por ejemplo, la sintaxis siguiente funciona:
<Button>Control.Background PE
<Control.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="Yellow" Offset="0.0" />
<GradientStop Color="LimeGreen" Offset="1.0" />
</LinearGradientBrush>
</Control.Background>
</Button>
Aquí, el elemento de propiedad se dio como Control.Background
aunque el elemento de propiedad estuviera contenido en Button
.
Pero al igual que typeName.memberName en forma para atributos, baseTypeName.memberName es un estilo deficiente en el marcado y debería evitarse.
Consulte también
.NET Desktop feedback