MVVM в .NET MAUI. Параметры команды

Команды в .NET MAUI для выполнения своей работы могут принимать некие параметры извне. Параметры команды, обычно передаются через свойство CommandParameter элементов управления.

Параметры команды в .NET MAUI

Вернемся немного назад и посмотрим на методы интерфейса ICommand:

bool CanExecute(object? parameter);
void Execute(object? parameter);

оба этих метода могут принимать в качестве параметра произвольный объект (object), который может использоваться далее в методе. Рассмотрим использование параметров команд на примере приложения из предыдущей части.

Пример использования параметров команды

Объявление команды с параметром

На данный момент в нашей модели представления уже имеется одна команда — AddCommand которая не принимает никаких параметров и добавляет новый объект типа Project в коллекцию. Вот как выглядит модель представления на данный момент:

public class ProjectViewModel : INotifyPropertyChanged
{
    private Project project = new() 
    {
        Id = 1,
        Name = "MVVM в .NET MAUI",
        Description = "Изучаем применение шаблона MVVM в .NET MAUI",
        Author = "Vlad (csharp.webdelphi.ru)",
    };

    public ObservableCollection<Project> Projects { get; set; } = [];

    public ICommand AddCommand { get; set; }

    public ProjectViewModel() 
    {
        AddCommand = new Command(() => 
        {
            Project project = new()
            {
                Id = Projects.Count + 1,
                Name = this.Name,
                Description = this.Description,
                Author = this.Author
            };

            Projects.Add(project);
            Id = -1;
            Name = string.Empty;
            Description = string.Empty;
            Author = string.Empty;
        });
    }

    public string Name
    {
        get => project.Name;
        set
        {
            if (project.Name != value)
            {
                project.Name = value;
                OnPropertyChanged();
            }
        }
    }
    public int Id
    {
        get => project.Id;
        set
        {
            if (project.Id != value)
            {
                project.Id = value;
                OnPropertyChanged();
            }
        }
    }
    public string Description
    {
        get => project.Description;
        set
        {
            if (project.Description != value)
            {
                project.Description = value;
                OnPropertyChanged();
            }
        }
    }
    public string Author
    {
        get => project.Author;
        set
        {
            if (project.Author != value)
            {
                project.Author = value;
                OnPropertyChanged();
            }
        }
    }

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

Самый очевидный пример, когда нам может потребоваться параметр в команде — это удаление или редактирование объекта. Например, добавим в класс следующую команду:

Для сокращения исходного кода, в листинге ниже показаны только изменения в классе.
public class ProjectViewModel : INotifyPropertyChanged
{
    
    public ICommand RemoveCommand { get; set; }

    public ProjectViewModel() 
    {
        RemoveCommand = new Command((param) => 
        {
            if (param is Project proj)
            {
                Projects.Remove(proj);
            }
        });
    }
}

Команда RemoveCommand принимает в качестве параметра объект. Если этот объект имеет тип Project, то команда выполняет удаление проекта из списка Projects.

Привязка парам в пользовательском интерфейсе

Чтобы привязать элемент управления к команде, изменим код страницы 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="MvvmExample.MainPage"
             xmlns:models ="clr-namespace:MvvmExample.Models"
             xmlns:local ="clr-namespace:MvvmExample.ViewModels"
             x:DataType="local:ProjectViewModel">

    <ScrollView>
        <VerticalStackLayout Padding="15" Margin="15">
            <Label Text="Название проекта" />
            <Entry Text="{Binding Name}" FontAttributes="Bold" />
            <Label Text="Описание" />
            <Entry Text="{Binding Description}" FontAttributes="Bold" />
            <Label Text="Автор" />
            <Entry Text="{Binding Author}" FontAttributes="Bold" />
            <Button Text="Добавить" Command="{Binding AddCommand}"/>

            <CollectionView x:Name="ProjectsView" SelectionMode="Single" ItemsSource="{Binding Projects}" Margin="15">
                <CollectionView.ItemTemplate>
                    <DataTemplate x:DataType="{x:Type models:Project}">
                        <Border StrokeShape="Rectangle" Background="LightGreen">
                            <VerticalStackLayout>
                                <Label Text="{Binding Name}" FontSize="16" FontAttributes="Bold" TextColor="Blue"/>
                                <Label Text="{Binding Description}"/>
                                <Label Text="{Binding Author}"/>
                            </VerticalStackLayout>
                        </Border>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>
            <Button Text="Удалить" Command="{Binding RemoveCommand}" CommandParameter="{Binding Source={x:Reference ProjectsView}, Path=SelectedItem}"></Button>
        </VerticalStackLayout>
    </ScrollView>

</ContentPage>

Здесь, по сравнению с предыдущим примером, мы внесли следующие изменения:

добавили имя элементу CollectionView и изменили шаблон данных:

<CollectionView x:Name="ProjectsView" SelectionMode="Single" ItemsSource="{Binding Projects}" Margin="15">
    <CollectionView.ItemTemplate>
        <DataTemplate x:DataType="{x:Type models:Project}">
            <Border StrokeShape="Rectangle" Background="LightGreen">
                <VerticalStackLayout>
                    <Label Text="{Binding Name}" FontSize="16" FontAttributes="Bold" TextColor="Blue"/>
                    <Label Text="{Binding Description}"/>
                    <Label Text="{Binding Author}"/>
                </VerticalStackLayout>
            </Border>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

Также мы установили режим выделения элементов в CollectionView как Single, то есть выделять можно только один элемент списка за раз. Под элементом CollectionView мы разместили новую кнопку к которая и привязана к нашей новой команде:

<Button Text="Удалить" Command="{Binding RemoveCommand}" CommandParameter="{Binding Source={x:Reference ProjectsView}, Path=SelectedItem}"></Button>

Для использования параметра мы задали у кнопки значение свойства CommandParameter для которого также использовали привязку, но уже к свойству SelectedItem (выделенный элемент) уCollectionView.

Что касается передачи модели представления в свойство BindingContext страницы, то здесь мы никаких изменений не делаем: ProjectViewModel регистрируется как сервис в MauiProgram.cs

builder.Services.AddSingleton<ProjectViewModel>();//регистрируем сервис

и передается через конструктор MainPage в свойство:

public partial class MainPage : ContentPage
{
    public MainPage(ProjectViewModel model)
    {
        InitializeComponent();
        BindingContext = model;
        
    }
}

Запустим приложение и проверим работу. Вид страницы после добавления нового проекта в список будет таким:Параметры командыПосле того, как вы кликните по элементу в списке и затем по кнопке «Удалить» проект будет удален из списка

Параметры команды

Итого

Параметры команды задаются через свойство CommandParameter у элементов управления, поддерживающих механизм команд в .NET MAUI, например, у кнопки. Использование параметров позволяет передавать в команду какие-либо данные извне, например, удаляемые объекты, идентификаторы изменяемых объектов и так далее.

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