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