2015-01-14 3 views
1

У меня есть следующий сценарий:Вызов метода в ViewModel без команды

public class MyCommand : ICommand 
{ 
    MyViewModel _viewModel; 

    public MyCommand(MyViewModel viewModel) 
    { 
     _viewModel = viewModel; 
    } 

    public bool CanExecute(object parameter) 
    { 
     return true; 
    } 

    public event EventHandler CanExecuteChanged; 

    public void Execute(object parameter) 
    { 
     _viewModel.SomeMethod(); 
    } 
} 

По существу, эта команда будет просто вызывать метод в моем ViewModel, когда кнопка нажата. CanExecute всегда возвращает true.

Проблема в том, что, хотя это, как правило, считается лучшим способом делать вещи, оно не очень элегантно. Он задает вопрос о том, зачем мне нужна команда для выполнения этого очень простого процесса.

Почему я не могу просто пропустить команду и вызвать метод напрямую?

У меня было думать об этом, и единственный способ, которым я могу видеть, чтобы достичь этого было бы создать команду, где я могу указать имя метода, который я хочу, чтобы позвонить в CommandParameter собственности на моя кнопка.

Я надеюсь, что кто-то еще может предложить элегантное решение этой проблемы.

+1

1) Это не считается лучшим способом делать вещи 2) вы можете вызвать метод непосредственно, но вы должны прыгать через обручи идиотов в пользовательском интерфейсе, чтобы сделать это, что есть дороже, чем использование схемы ICommand. – Will

+0

Вы также разделяете логику между двумя частями, то есть 'View' и' ViewModel', если кто-нибудь придет и сохранит этот код, им придется искать в 2-х местах, а не в одном, т. Е. 'ViewModel'. – XAMlMAX

ответ

2

Вы можете использовать RelayCommand из MVVMLight или DelegateCommand из PRISM. Оба они предоставят общий способ выполнения команд. Или даже вы можете создать свой собственный общий класс команд и использовать его. См. Образец ниже.

public class ViewModel : INotifyPropertyChanged 
    { 
     public BaseCommand GetDataCommand { get; set; } 

     public ViewModel() 
     { 
      GetDataCommand = new BaseCommand(GetData);    
     } 

     private void GetData(object param) 
     { 

     } 
    } 

    public class BaseCommand : ICommand 
    { 
     private Predicate<object> _canExecute; 
     private Action<object> _method; 
     public event EventHandler CanExecuteChanged 
     { 
      add 
      { 
       CommandManager.RequerySuggested += value; 
      } 
      remove 
      { 
       CommandManager.RequerySuggested -= value; 
      } 
     } 

     public BaseCommand(Action<object> method, Predicate<object> canExecute=null) 
     { 
      _method = method; 
      _canExecute = canExecute; 
     } 

     public bool CanExecute(object parameter) 
     { 
      if (_canExecute == null) 
      { 
       return true; 
      } 

      return _canExecute(parameter); 
     } 

     public void Execute(object parameter) 
     { 
      _method.Invoke(parameter); 
     } 
    } 
4

Вы можете использовать «CallMethodAction» действие от Blend SDK вызова метода на модели представления с вашей точки зрения. Это будет выглядеть примерно так:

<Button ...> 
    <i:Interaction.Triggers> 
    <i:EventTrigger EventName="Click"> 
     <ei:CallMethodAction MethodName="MyMethod" TargetObject="{Binding}" /> 
    </i:EventTrigger> 
    </i:Interaction.Triggers> 
</Button> 

Однако по-прежнему считается лучшей практикой использования команд для этого. Как отметил Айяппан, вы можете использовать библиотеку, такую ​​как MVVM Light Toolkit, поэтому вам не нужно писать собственную реализацию ICommand.

PS: Смотрите также WPF: MVVM: Command vs CallMethodAction?

Смежные вопросы