Roberto Sánchez Programador/Desarrollador .NET

Extensiones de marcado.

Ya hemos aprendido a actuar sobre las propiedades de los elementos mediante la modificación de las mismas o mediante la modificación de sus atributos. Sin embargo, XAML ofrece la posibilidad de actuar sobre los elementos a través del procesamiento de una clase que decidirá en tiempo de ejecución. Esto quiere decir que, mediante las extensiones de marcado, podremos establecer en el código XAML que el valor de las propiedades puedan cambiar a lo olargo de la ejecución del programa de manera automática según lo establecido sin que sea necesario que lo hagamos manualmente.

Las extensiones de marcado más comunes son aquellas que admiten referencias de recursos ('StaticResource' y 'DynamicResource') y aquellas que admiten enlace de datos ('Binding'). Estos tres tipos de extensiones de marcado son muy importantes a la hora de la contrucción de grandes aplicaciones WPF, por lo que es fundamental que te quedes bien con este tema.

Vamos a ver un ejemplo sobre la ventana inicial que habíamos creado, concretamente en el interior del contenedor principal 'Grid':

<Grid>
    <Grid.Resources>
        <SolidColorBrush x:Key="backgroundColor" Color="Azure"/>
    </Grid.Resources>
    <Button Content="Aceptar" Name="buttonAccept" Background="{DynamicResource ResourceKey=backgroundColor}"/>
</Grid>

Analicemos el código fuente: hemos creado un recurso del contenedor principal 'Grid' que hace referencia al color del sistema nombrado con 'Azure' para utilizarlo más adelante; después hemos creado un control 'Button' y a su propiedad 'Background' la hemos asociado una extensión de marcado de tipo 'DynamicResource' que enlaza directamente con el recurso del 'Grid'. Esta acción puede parecer que hemos escrito más código fuente del necesario. Sin embargo, no debes dejarte llevar por esa impresión, pues al haberlo hecho de esta manera esa propiedad podrá cambiar de valor de forma automática en tiempo de ejecución. ¿Por ejemplo? Piensa en una aplicación que permite cambiar la máscara del tema de presentación, con dos colores de fondo, uno claro y otro oscuro... O para ir más lejos, piensa en una aplicación que cambia de idioma inmediatamente, sin ser necesario que ejecutemos de nuevo la aplicación para que cargue el idioma seleccionado.

También podemos hacer uso de la extensión de marcado 'StaticResource'. La diferencia con la siguiente la irás comprendiendo más adelante. De momento entiende bien su uso, muy similar al de la extensión de marcado 'DynamicResource':

<Grid>
    <Grid.Resources>
        <Style x:Key="lightBlueBackground">
            <Setter Property="Control.Background" Value="LightBlue"/>
        </Style>
    </Grid.Resources>
    <Button Content="Aceptar" Name="buttonAccept" Background="{StaticResource ResourceKey=lightBlueBackground}"/>
</Grid>

Otra posibilidad con las extensiones de marcado es hacer uso de 'Binding', o enlace:

<Button Content="Aceptar" Name="buttonAccept">
    <Button.Background>
        <SolidColorBrush Color="Blue"/>
    </Button.Background>
</Button>
<Button Content="Cancelar" Name="buttonCancel" Background="{Binding Background, ElementName=buttonAccept}"/>

Fácil: hemos enlazado la propiedad 'Background' del botón 'buttonCancel' con la propiedad 'Background' del botón 'buttonAccept', de tal manera que el segundo botón copiará el color de fondo del primero. Más adelante verás que esta copia de los valores de las propiedades pueden copiarse en un sentido, en otro o en ambos sentidos, así como una sola vez o en todo momento.

Hay otras extensiones de marcado, menos usadas pero también importantes:

x:Null: devuelve un objeto 'null' que permita establecer una referencia 'null'.

x:Type: devuelve un objeto 'Type' que representa al tipo especificado.

x:Static: para obtener valores de propiedades o atributos estáticos.

x:Array: permite crear una tabla de elementos.

RelativeResource: describe la ubicación del origen del enlace relativa a la posición del destino para un objeto 'Binding'.

TemplateBinding: admite el enlace entre el valor de una propiedad y una plantilla y el valor de alguna otra propiedad expuesta en el control con plantilla.