Привязка в .NET MAUI. Привязка списков и шаблоны данных (DataTemplate)

Довольно часто, при работе над приложением .NET MAUI нам требуется сделать привязку не к отдельному объекту и его свойству, а сразу к списку объектов. Например, чтобы вывести на экран список пользователей, проектов, задач и так далее. На данный момент мы уже знаем про такой элемент управления, как Picker. В этой части мы рассмотрим то, как можно заполнить этот элемент списком объектов, а также раздеремся с шаблонами данных на примере еще одного элемента — CollectionView.

Заполнение Picker списком объектов

Теперь, когда мы изучили основы привязки данных в .NET MAUI, можно рассмотреть ещё один вариант работы с элементом Picker и заполнить список его элементов, используя объекты своего класса. Для примера, воспользуемся классом Project, который мы рассматривали в предыдущей части. Вот как выглядит наш класс:

public class Project : INotifyPropertyChanged
{
    string name = "";
    bool isActive = false;
    double cost = 0;
    public string Name
    {
        get => name;
        set
        {
            if (name != value)
            {
                name = value;
                OnPropertyChanged();
            }
        }
    }
    public bool IsActive
    {
        get => isActive;
        set
        {
            if (isActive != value)
            {
                isActive = value;
                OnPropertyChanged();
            }
        }
    }
    public double Cost
    {
        get => cost;
        set
        {
            if (cost != value)
            {
                cost = value;
                OnPropertyChanged();
            }
        }
    }

    public event PropertyChangedEventHandler? PropertyChanged;

    public void OnPropertyChanged([CallerMemberName] string prop = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop));
    }
}

Используем объекты этого класса для заполнения списка. Добавим на страницу MainPage следующий ресурс:

<ContentPage.Resources>
    <ResourceDictionary>
        <x:Array x:Key="Projects" Type="{x:Type local:Project}">
            <local:Project Name="Проект №1" IsActive="True" Cost="120"/>
            <local:Project Name="Проект №2" IsActive="True" Cost="130"/>
            <local:Project Name="Проект №3" IsActive="True" Cost="140"/>
            <local:Project Name="Проект №4" IsActive="True" Cost="150"/>
            <local:Project Name="Проект №5" IsActive="True" Cost="160"/>
        </x:Array>
    </ResourceDictionary>
</ContentPage.Resources>

Зная основы привязки, мы можем легко привязать этот массив объектов к списку Picker.ItemSource, например так:

<VerticalStackLayout BindingContext="{StaticResource Projects}">
    <Picker ItemsSource="{StaticResource Projects}" ItemDisplayBinding="{Binding Path=Name}"/>
</VerticalStackLayout>

Здесь мы передаем в ItemSource массив и дополнительно привязываем свойство Picker.ItemDisplayBinding к свойству Name класса Project. Теперь наш список будет таким:

Более того, мы можем ещё сократить этот код. Так как контекст привязки определен в родительском контейнере и это, по сути, всё тот же массив элементов, то мы можем привязаться к нему используя расширение разметки Binding вот так:

<VerticalStackLayout BindingContext="{StaticResource Projects}">
    <Picker ItemsSource="{Binding}" ItemDisplayBinding="{Binding Path=Name}"/>
</VerticalStackLayout>

Результат работы приложение будет точно таким же, как и на рисунке выше.

Шаблоны данных (DataTemplate)

Рассмотрим ещё один пример работы с коллекциями объектов на примере пока ещё не изученного нами элемента управления — CollectionView. Элемент CollectionView предназначен для отображения списка однотипных данных. Этот элемент имеет достаточно гибкую систему различных настроек и, как следствие, содержит множество свойств для работы. Однако мы сосредоточимся на главном и разберемся с тем как заполнить CollectionView коллекцией объектов своего класса. Для работы нам потребуется всего два свойства CollectionView:

Свойство Тип Описание
ItemsSource IEnumerable Коллекция объектов, которые необходимо отобразить в списке
ItemTemplate DataTemplate Шаблон данных

Элемент CollectionView предназначен для отображения данных любых объектов и изначально, если передать в свойстве ItemSource коллекцию объектов, то CollectionView будет пытаться отобразить эти данные, используя метод ToString() класса. Например, вернемся к нашему приложению и добавим в него новый элемент управления:

<VerticalStackLayout BindingContext="{StaticResource Projects}">
    <Picker ItemsSource="{Binding}" ItemDisplayBinding="{Binding Path=Name}"/>
    <CollectionView ItemsSource="{Binding}"/>
</VerticalStackLayout>

В результате, мы увидим вот такой список объектов:

Можно было бы переопределить в нашем классе метод ToString() и выводить в список необходимые нам строки, но это не самый лучший вариант так как нам может потребоваться использовать свойства объектов в различных вариациях в разных элементах управления. Здесь нам и потребуется второе свойство — ItemTemplate

Перепишем код элемента следующим образом:

<CollectionView ItemsSource="{Binding}">
    <CollectionView.ItemTemplate>
        <DataTemplate x:DataType="{x:Type local:Project}">
            
                <Border Background="LightGray" Padding="5">
                    <VerticalStackLayout>
                        <Label Text="{Binding Name}"/>
                        <CheckBox IsChecked="{Binding IsActive}"/>
                        <Label Text="{Binding Cost}"/>
                    </VerticalStackLayout>
                </Border>
            
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

В свойстве ItemTemplate мы указываем шаблон данных, то есть то, как наш объект должен отображаться в списке. Свойство x:DataType у DataTemplate указывает объект какого типа будет участвовать при формировании шаблона:

<DataTemplate x:DataType="{x:Type local:Project}">

Далее, внутри DataTemplate мы указываем как визуально будет отображаться объект — здесь мы можем использовать любые элементы управления, применять к ним стили, задействовать другие ресурсы и так далее. Стоит обратить внимание на то как производится привязка к свойствам объекта. Так как тип объекта известен, а коллекция таких объектов уже привязана к свойству ItemSource, то мы используем при привязке только имена свойств:

<Label Text="{Binding Name}"/>
<CheckBox IsChecked="{Binding IsActive}"/>
<Label Text="{Binding Cost}"/>

В итоге, в приложении будет сформирован вот такой список проектов:

Итого

Используя привязку в .NET MAUI мы можем привязывать к элементам управления коллекции объектов. Для отображения данных сложных объектов удобно пользоваться шаблонами данных, определяя свойство ItemTemplate типа DataTemplate у элемента управления.

Подписаться
Уведомить о
guest
0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии