Definir y usar recursos
Un recurso es como una constante simbólica de un lenguaje de programación. Se define en un lugar y se hace referencia a él allá donde se necesite. Facilita la lectura del código gracias al empleo de un nombre descriptivo en lugar de un valor "mágico". Si necesita cambiar el valor, solo tiene que actualizar la definición.
En este módulo verá cómo usar recursos para eliminar valores codificados de forma rígida del XAML.
¿Qué es un recurso?
Un recurso es cualquier objeto que se puede compartir en la interfaz de usuario. Los ejemplos más comunes son las fuentes, los colores y los tamaños. Pero también puede almacenar objetos complejos como instancias de Style y OnPlatform como recursos.
Un recurso se define en XAML o en código. Luego se aplica en XAML o en código. Por lo general, trabajará completamente en XAML, aunque más adelante le mostraremos algunos casos donde el código resulta útil.
Considere este un ejemplo. Imagine que quiere usar los mismos valores TextColor en los controles de una página. Si usa valores codificados de forma rígida, el XAML tiene un aspecto similar al siguiente. Observe cómo el valor del color del texto se repite en los dos controles.
<Label TextColor="Blue" FontSize="14">
<Button TextColor="Blue" FontSize="14">
En lugar de repetir el color del texto, puede definirlo como un recurso. La definición tiene un aspecto similar a este XAML:
<Color x:Key="PageControlTextColor">Blue</Color>
Observe que el elemento definido tiene una propiedad x:Key que asigna un nombre al recurso. Usa esta clave para buscar el recurso en el XAML.
Para poder usar un recurso, primero debe almacenarlo en un diccionario de recursos.
¿Qué es un elemento ResourceDictionary?
ResourceDictionary es una clase de biblioteca de .NET MAUI que se personaliza para su uso con recursos de interfaz de usuario. Es un diccionario, por lo que almacena pares clave-valor. El tipo de la clave se limita a String, mientras que el valor puede ser cualquier objeto.
Cada página XAML de .NET MAUI tiene una propiedad denominada Resources que puede contener un objeto ResourceDictionary. La propiedad es NULL de forma predeterminada, por lo que tiene que crear una instancia del diccionario para poder usarla. En el código siguiente se muestra cómo se crea un objeto ResourceDictionary y se asigna a la propiedad Resources de ContentPage:
<ContentPage.Resources>
<ResourceDictionary>
...
</ResourceDictionary>
</ContentPage.Resources>
El XAML de .NET MAUI tiene una cómoda sintaxis integrada que crea la instancia del diccionario de forma automática cada vez que se empieza a usar la propiedad Resources. El ejemplo anterior se puede simplificar con el código siguiente:
<ContentPage.Resources>
...
</ContentPage.Resources>
Cada página de la aplicación puede tener su propio diccionario. Estos diccionarios específicos de la página se usan para almacenar los recursos que se emplean exclusivamente en esa página.
Nota:
Cada control de una página también puede tener su propio diccionario de recursos. Por ejemplo, puede agregar un directorio de recursos a un control Label como este:
<Label Text="Hello, World!"
...
<Label.Resources>
...
</Label.Resources>
</Label>
Aparte de en diseños y vistas, que pueden contener elementos secundarios, no es habitual hacerlo en el nivel de control.
Creación de un recurso
Para crear un recurso, debe declararlo dentro de la propiedad Resources de una página. En el ejemplo siguiente se crea el recurso de color de texto que se describe anteriormente.
<ContentPage.Resources>
<Color x:Key="PageControlTextColor">Blue</Color>
</ContentPage.Resources>
Cuando seleccione una clave para el recurso, elija un nombre que refleje el uso, en lugar del valor del recurso. Por ejemplo, para establecer el fondo de una etiqueta en Red, no use RedColor como clave, use BackgroundColor en su lugar.
Aplicar un recurso mediante un elemento StaticResource
StaticResource es una extensión de marcado para buscar recursos en un diccionario de recursos. Se proporciona la clave del recurso y la extensión de marcado devuelve el valor correspondiente. En el marcado XAML siguiente se muestra un ejemplo que crea y usa un recurso Color
denominado PageControlTextColor. En el marcado XAML para el control de etiqueta del ejemplo se usa la extensión de marcado StaticResource para recuperar el valor.
<ContentPage.Resources>
<Color x:Key="PageControlTextColor">Blue</Color>
</ContentPage.Resources>
...
<Label TextColor="{StaticResource PageControlTextColor}" ... />
La extensión se denomina StaticResource porque la extensión se evalúa solo una vez. La búsqueda en el diccionario se produce cuando se crea el objeto de destino. La propiedad de destino no se actualiza si cambia el valor del recurso en el diccionario.
Advertencia
StaticResource inicia una excepción en tiempo de ejecución si no se encuentra la clave.
Tipos intrínsecos de XAML
En el ejemplo original que se presenta al principio de esta unidad se establece la propiedad TextColor y la propiedad FontSize:
<Label TextColor="Blue" FontSize="14">
<Button TextColor="Blue" FontSize="14">
FontSize tiene el tipo Double. Para crear un recurso para este valor, use uno de los tipos intrínsecos XAML definidos en la especificación XAML. La especificación XAML define nombres de tipo de muchos de los tipos simples de C#. En el código siguiente se muestran recursos de ejemplo de cada uno de los tipos intrínsecos.
<ContentPage.Resources>
<x:String x:Key="...">Hello</x:String>
<x:Char x:Key="...">X</x:Char>
<x:Single x:Key="...">31.4</x:Single>
<x:Double x:Key="...">27.1</x:Double>
<x:Byte x:Key="...">8</x:Byte>
<x:Int16 x:Key="...">16</x:Int16>
<x:Int32 x:Key="...">32</x:Int32>
<x:Int64 x:Key="...">64</x:Int64>
<x:Decimal x:Key="...">12345</x:Decimal>
<x:TimeSpan x:Key="...">1.23:5959</x:TimeSpan>
<x:Boolean x:Key="...">True</x:Boolean>
</ContentPage.Resources>
Establecimiento de valores específicos de la plataforma para un recurso
Es habitual tener que ajustar ligeramente la interfaz de usuario de la aplicación entre plataformas. La forma estándar de definir los valores específicos de la plataforma es usar un objeto OnPlatform al definir un recurso. Por ejemplo, en el código siguiente se muestra cómo se crea un recurso que hace referencia a diferentes colores de texto en iOS, Android, macOS (Mac Catalyst) y Windows (WinUI).
<ContentPage.Resources>
<OnPlatform x:Key="textColor" x:TypeArguments="Color">
<On Platform="iOS" Value="Silver" />
<On Platform="Android" Value="Green" />
<On Platform="WinUI" Value="Yellow" />
<On Platform="MacCatalyst" Value="Pink" />
</OnPlatform>
</ContentPage.Resources>
...
<Label TextColor="{StaticResource textColor}" ... />