Содержание
Команды в .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, например, у кнопки. Использование параметров позволяет передавать в команду какие-либо данные извне, например, удаляемые объекты, идентификаторы изменяемых объектов и так далее.
