Язык программирования C#9 и платформа .NET5
Часть 571 из 642 Информация о книге
Padding="4, 2" Command="{Binding Path=ChangeColorCmd,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}"CommandParameter="{Binding ElementName=cboCars, Path=SelectedItem}"/>Тестирование приложения
Запустите приложение. Кнопка Change Color не будет доступной (рис. 28.8), т.к. автомобиль еще не выбран.
Теперь выберите автомобиль; кнопка Change Color становится доступной, а щелчок на ней обеспечивает изменение цвета, как и ожидалось!
Создание класса CommandBase
Если распространить такой шаблон на
, то итогом стал бы код, повторяющийся среди классов. Это хороший знак о том, что необходим базовый класс. Создайте внутри папкиAddCarCommand.csновый файл класса по имениCmdsи добавьте операторCommandBase.csдля пространства именusing. Сделайте классSystem.Windows.Inputоткрытым и реализующим интерфейсCommandBase. Превратите класс и методыICommandиExecute()в абстрактные. Наконец, добавьте обновление в событиеCanExecute()из классаCanExecuteChanged. Ниже показана полная реализация:ChangeColorCommandusing System;using System.Windows.Input;namespace WpfCommands.Cmds{public abstract class CommandBase : ICommand{public abstract bool CanExecute(object parameter);public abstract void Execute(object parameter);public event EventHandler CanExecuteChanged{add => CommandManager.RequerySuggested += value;remove => CommandManager.RequerySuggested -= value;}}}Добавление класса AddCarCommand
Добавьте в папку
новый файл класса по имениCmds. Сделайте класс открытым и укажитеAddCarCommand.csв качестве базового класса. Поместите в начало файла следующие операторыCommandBase:usingusing System.Collections.ObjectModel;using System.Linq;using WpfCommands.Models;Ожидается, что параметр должен иметь тип
, поэтому предусмотрите в методеObservableCollection<Car>соответствующую проверку. Если параметр относится к типуCanExecute(), тогда методObservableCollection<Car>должен добавить дополнительный объектExecute()подобно обработчику событияCar.Clickpublic class AddCarCommand :CommandBase{public override bool CanExecute(object parameter)=> parameter is ObservableCollection<Car>;public override void Execute(object parameter){if (parameter is not ObservableCollection<Car> cars){return;}var maxCount = cars.Max(x => x.Id);cars.Add(new Car{Id = ++maxCount,Color = "Yellow",Make = "VW",PetName = "Birdie"});}}Изменение файла MainWindow.xaml.cs
Добавьте открытое свойство типа
по имениICommandс поддерживающим полем. В теле выражения для свойства возвратите значение поддерживающего поля (создавая экземплярAddCarCmd, если поддерживающее поле равноAddCarCommand):nullprivate ICommand _addCarCommand = null;public ICommand AddCarCmd=> _addCarCommand ??= new AddCarCommand());Изменение файла MainWindow.xaml
Модифицируйте разметку XAML, удалив атрибут
и добавив атрибутыClickиCommand. ОбъектCommandParameterбудет получать список автомобилей из поля со спискомAddCarCommand. Ниже показана полная разметка XAML для кнопки:cboCars<Button x:Name="btnAddCar" Content="Add Car" Margin="5,0,5,0" Padding="4, 2"Command="{Binding Path=AddCarCmd,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}"CommandParameter="{Binding ElementName=cboCars, Path=ItemsSource}"/>
