Наследование RelayCommand во ViewModelC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Наследование RelayCommand во ViewModel

Сообщение Anonymous »

Я разрабатываю схему модели представления «основной/подробный», поэтому создал базовый класс, который реализует команды «Добавить», «Редактировать», «Сохранить», «Отменить» и «Удалить», а также управляет логикой CanExecute для этих команд. Однако команды «Сохранить» и «Удалить» необходимо частично реализовать в производном классе, но они все равно должны присутствовать в базовом классе для управления логикой CanExecute.
Короче , я попробовал наследование 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();
}
}
Но если сделать это таким образом, произойдет ошибка в функции NotifyButtonsState(), которая уведомляет о состоянии кнопок:

Код: Выделить всё

   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]
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Как передать информацию из представления XAML в RelayCommand в ViewModel в .NET MAUI?
    Anonymous » » в форуме C#
    0 Ответы
    19 Просмотры
    Последнее сообщение Anonymous
  • Каков общий способ обработки CS8602 в RelayCommand WPF?
    Anonymous » » в форуме C#
    0 Ответы
    16 Просмотры
    Последнее сообщение Anonymous
  • Как использовать [RelayCommand] в базовом классе
    Anonymous » » в форуме C#
    0 Ответы
    9 Просмотры
    Последнее сообщение Anonymous
  • Как использовать [RelayCommand] в базовом классе
    Anonymous » » в форуме C#
    0 Ответы
    13 Просмотры
    Последнее сообщение Anonymous
  • CommunityToolkit.Mvvm.Input.RelayCommand не работает на iOS (MAUI .NET 8.0)?
    Anonymous » » в форуме C#
    0 Ответы
    16 Просмотры
    Последнее сообщение Anonymous

Вернуться в «C#»