Содержание
Под термином «ресурсы приложения» может пониматься практически всё, что используется в нашем приложении — картинки, статические файлы, строки и так далее. В нашем случае, под ресурсами мы будем рассматривать логические ресурсы, то есть такие ресурсы, которые мы можем определить внутри приложения и использовать их в нескольких элементах приложение. Так, в качестве ресурсов мы можем рассматривать строки, значения цветов, объекты и так далее.
Класс ResourceDictionary и виды ресурсов приложения
Класс ResourceDictionary в .NET MAUI выступает в качестве репозитория ресурсов приложения. К типичным ресурсам, хранящимся в ResourceDictionary можно отнести: стилях, шаблоны элементов управления, шаблонах данных, конвертеры свойств и цвета. Так как ресурсы хранятся, по сути, в словаре, то для каждого ресурса с помощью атрибута x:Key задается свой уникальный ключ по которому в дальнейшем мы можем к этому ресурсу обратиться.
В приложении .NET MAUI каждый элемент управления, который является наследником VisualElement, включая страницы приложения содержит свойство Resources в котором могут размещаться словари ресурсов. Таким образом, условно, все ресурсы в .NET MAUI можно разделить на следующие группы:
- Ресурсы представления, например кнопки (
Button) могут применяться только к конкретному объекту. - Ресурсы макета (контейнера компоновки), например
StackLayoutилиGrid, могут применяться как к макету, так и ко всем дочерним элементам. - Ресурсы, определенные на уровне страницы, можно применять к странице и ко всем его дочерним элементам.
- Ресурсы, определенные на уровне приложения, могут применяться во всем приложении.
В шаблонном проекте .NET MAUI уже определено множество различных ресурсов, однако мы будем разбираться с ними последовательно. К примеру, уже изучили такой элемент управления, как Picker для которого необходимо передать список объектов для отображения в выпадающем списке. Этот список может быть неизменным и тогда может оказать целесообразным вынести его в качестве ресурса, например, на уровне страницы. Чтобы продемонстрировать сказанное, создадим новое приложение .NET MAUI и изменим код страницы MainPage.xaml следующим образом:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiResources.MainPage">
<ContentPage.Resources>
<ResourceDictionary>
<x:Array Type="{x:Type x:String}" x:Key="pickerElements">
<x:String>Элемент 1</x:String>
<x:String>Элемент 2</x:String>
<x:String>Элемент 3</x:String>
<x:String>Элемент 4</x:String>
</x:Array>
</ResourceDictionary>
</ContentPage.Resources>
</ContentPage>
Также, удалите из файла отдельного кода страницы обработчик клика по кнопке. Сейчас на странице определен словарь ресурсов, который содержит массив строк:
<x:Array Type="{x:Type x:String}" x:Key="pickerElements">
<x:String>Элемент 1</x:String>
<x:String>Элемент 2</x:String>
<x:String>Элемент 3</x:String>
<x:String>Элемент 4</x:String>
</x:Array>
Так как массив выступает в качестве ресурса, то мы определили для него атрибут x:Key. Теперь мы можем воспользоваться этим ресурсом в любом месте нашей страницы. Чтобы использовать ресурс в разметке XAML мы должны использовать расширение StaticResource или DynamicResource.
Расширение XAML StaticResource
StaticResource — это расширение XAML, благодаря которому мы можем получать значения ресурсов. Это расширение наиболее часто используется в .NET MAUI. Сам поиск ресурса производится в следующей последовательности:
- Для StaticResource указывается ключ ресурса, значение которого необходимо получить из словаря ресурсов.
- запрошенный ключ проверяется в словаре ресурсов на уровне элемента в котором производится запрос ресурса (например, на уровне Picker), если ресурс существует, то он возвращается, а процесс подстановки на этом завершается.
- Если совпадение не найдено, процесс подстановки выполняет поиск по визуальному дереву вверх, проверяя словарь ресурсов каждого родительского элемента.
- Если совпадение не найдено в корневом элементе, проверяется словарь ресурсов уровня приложения.
- Если совпадение по-прежнему не найдено, то вызывается исключение типа
XamlParseException.
Используем расширение StaticResource в нашем приложении. Добавим на страницу MainPage элемент Picker:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiResources.MainPage">
<ContentPage.Resources>
<ResourceDictionary>
<x:Array Type="{x:Type x:String}" x:Key="pickerElements">
<x:String>Элемент 1</x:String>
<x:String>Элемент 2</x:String>
<x:String>Элемент 3</x:String>
<x:String>Элемент 4</x:String>
</x:Array>
</ResourceDictionary>
</ContentPage.Resources>
<ScrollView>
<VerticalStackLayout
Padding="30,0"
Spacing="25">
<Picker ItemsSource="{StaticResource pickerElements}"></Picker>
</VerticalStackLayout>
</ScrollView>
</ContentPage>
Как можно видеть, по представленному выше коду, мы запрашиваем массив строк для свойства ItemsSource, указав ключ ресурса:
<Picker ItemsSource="{StaticResource pickerElements}"></Picker>
Запустим приложение и проверим его работу:
Расширение XAML DynamicResource
Расширение DynamicResource во многом схоже со StaticResource и используется аналогично. Различие заключается в том, что DynamicResource сохраняет ссылку на ресурс в словаре, что позволяет по ходу выполнение приложения изменять ресурс и использовать измененное значение, например, в визуальных элементах. Рассмотрим использование DynamicResource на примере. Добавим для нашего элемента Picker следующий обработчик события SelectedIndexChanged:
<Picker ItemsSource="{StaticResource pickerElements}" SelectedIndexChanged="Picker_SelectedIndexChanged"/>
namespace MauiResources
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
//обработчик
private void Picker_SelectedIndexChanged(object sender, EventArgs e)
{
string[] arr = ["Новое значение 1", "Новое значение 2", "Новое значение 3", "Новое значение 4"];
Resources["pickerElements"] = arr;
}
}
}
Здесь мы пытаемся получить доступ к ресурсу и заменить его значение на новый массив arr. Для доступа ресурсам мы используем свойство Resources. Так как на данный момент ресурс запрашивается с использованием расширения StaticResource то обработчик события сработает, однако в интерфейсе приложения ничего не поменяется.
Изменим XAML-код, используя DynamicResource:
<Picker ItemsSource="{DynamicResource pickerElements}" SelectedIndexChanged="Picker_SelectedIndexChanged"/>
Снова запустим приложение и выберем любой элемент в списке. Вы увидите, что в момент выбора все элементы списка полностью изменятся:
Таким образом, используя DynamicResource мы можем менять значения ресурсов в момент выполнения приложения и использовать их в компонентах.
Итого
Ресурсы приложения .NET MAUI хранятся в словаре ResourceDictionary. Ресурсы могут быть уровня представления (элемента), макета, страницы или приложения в целом. Для доступа к ресурсам приложения используются расширения XAML StaticResource или DynamicResource. Использование DynamicResource позволяет изменять ресурсы приложение по ходу выполнения приложения и использовать измененные значения.
