Короче , я попробовал наследование RelayCommand следующим образом:
Код: Выделить всё
// Base class
protected IRelayCommand SaveCommand { get; }
protected void Save()
{
// [...]
}
protected IRelayCommand DeleteCommand { get; }
protected void Delete()
{
// [...]
}
// Derived class
[RelayCommand(CanExecute = nameof(CanSave))]
private void Save()
{
// [...]
base.Save();
}
[RelayCommand(CanExecute = nameof(CanDelete))]
private void Delete()
{
// [...]
base.Delete();
}
Код: Выделить всё
internal abstract partial class MasterDetailViewModelBase : ObservableObject
{
// [...]
private TDetailViewModel? currentItem;
public TDetailViewModel? CurrentItem
{
get => currentItem;
set
{
if (EqualityComparer.Default.Equals(currentItem, value)) return;
SetProperty(ref currentItem, value);
OnPropertyChanged(nameof(HasCurrentItem));
NotifyButtonsState();
}
}
public bool HasCurrentItem => CurrentItem is not null;
private void NotifyButtonsState()
{
OnPropertyChanged(nameof(CanAdd));
OnPropertyChanged(nameof(CanEdit));
OnPropertyChanged(nameof(CanSave));
OnPropertyChanged(nameof(CanCancel));
OnPropertyChanged(nameof(CanDelete));
AddCommand.NotifyCanExecuteChanged(); // [NotifyCanExecuteChangedFor(nameof(AddCommand))]
EditCommand.NotifyCanExecuteChanged(); // [NotifyCanExecuteChangedFor(nameof(EditCommand))]
SaveCommand.NotifyCanExecuteChanged(); // [NotifyCanExecuteChangedFor(nameof(SaveCommand))]
CancelCommand.NotifyCanExecuteChanged(); // [NotifyCanExecuteChangedFor(nameof(CancelCommand))]
DeleteCommand.NotifyCanExecuteChanged(); // [NotifyCanExecuteChangedFor(nameof(DeleteCommand))]
}
public bool CanAdd => HasCurrentItem ? CurrentItem.State == ItemState.Unchanged : true;
public bool CanEdit => HasCurrentItem ? CurrentItem.State == ItemState.Unchanged : false;
public bool CanSave => HasCurrentItem ? CurrentItem.IsChanged : false;
public bool CanCancel => HasCurrentItem
? CurrentItem.State == ItemState.Adding ||
CurrentItem.State == ItemState.Editing
: false;
public bool CanDelete => HasCurrentItem ? CurrentItem.State == ItemState.Unchanged : false;
[RelayCommand(CanExecute = nameof(CanAdd))]
private void Add()
{
// [...]
}
[RelayCommand(CanExecute = nameof(CanEdit))]
private void Edit()
{
// [...]
}
//
// That's how CommunityToolkit.Mvvm implements the RelayCommand attribute:
//
//private RelayCommand? saveCommand;
//public IRelayCommand SaveCommand => saveCommand ??= new RelayCommand(new Action(Save), () => CanSave);
//
protected IRelayCommand SaveCommand { get; }
protected void Save()
{
// [...]
}
[RelayCommand(CanExecute = nameof(CanCancel))]
private void Cancel()
{
// [...]
}
protected IRelayCommand DeleteCommand { get; }
protected void Delete()
{
// [...]
}
}
Код: Выделить всё
internal partial class CustomersViewModel : MasterDetailViewModelBase
{
[RelayCommand(CanExecute = nameof(CanSave))]
private void Save()
{
// [...]
base.Save();
}
[RelayCommand(CanExecute = nameof(CanDelete))]
private void Delete()
{
// [...]
base.Delete();
}
}
Код: Выделить всё
private void NotifyButtonsState()
{
OnPropertyChanged(nameof(CanAdd));
OnPropertyChanged(nameof(CanEdit));
OnPropertyChanged(nameof(CanSave));
OnPropertyChanged(nameof(CanCancel));
OnPropertyChanged(nameof(CanDelete));
AddCommand.NotifyCanExecuteChanged();
EditCommand.NotifyCanExecuteChanged();
SaveCommand.NotifyCanExecuteChanged(); //
Подробнее здесь: [url]https://stackoverflow.com/questions/78664862/relaycommand-inheritance-in-viewmodel[/url]