2013-10-14 6 views
3

В моем проекте я хотел бы использовать команды MVVM (&). Я начал изучать команды и реализацию ICommand.Как реализовать ICommand без параметров

Я хотел бы создать реализацию ICommand без параметров. (Для того, чтобы вызвать загрузку данных/смыва данных и т.д. - не нужны никакие параметры, чтобы сделать это, так что это только кажется естественным, чтобы попытаться создать команду без параметров)

Это код, который я использую:

using System.Windows.Input; 

public class NoParameterCommand : ICommand 
{ 
    private Action executeDelegate = null; 
    private Func<bool> canExecuteDelegate = null; 
    public event EventHandler CanExecuteChanged = null; 

    public NoParameterCommand(Action execute) 
    { 
     executeDelegate = execute; 
     canExecuteDelegate =() => { return true; }; 
    } 
    public NoParameterCommand(Action execute, Func<bool> canExecute) 
    { 
     executeDelegate = execute; 
     canExecuteDelegate = canExecute; 
    } 

    public bool CanExecute() 
    { 
     return canExecuteDelegate(); 
    } 
    public void Execute() 
    { 
     if (executeDelegate != null) 
     { 
      executeDelegate(); 
     } 
    } 
} 

Но я получил сообщения об ошибках, не реализующий интерфейс ICommand в правильном порядке ('XXX.YYYY.NoParameterCommand' does not implement interface member 'System.Windows.Input.ICommand.Execute(object)')

Так я думал, что делать это, как это вместо:

(Добавлены параметры, которые отсутствовали из CanExecute и Execute)

public class NoParameterCommand : ICommand 
{ 
    ...omitted - no changes here... 

    public bool CanExecute(object parameter) //here I added parameter 
    { 
     return canExecuteDelegate(); 
    } 
    public void Execute(object parameter) //and here 
    { 
     if (executeDelegate != null) 
     { 
      executeDelegate(); 
     } 
    } 
} 
  1. Это хороший способ сделать это?
  2. ДОЛЖНЫ ИСПОЛЬЗОВАТЬ ДРУГОЙ ПУТЬ? (ЕСЛИ ТАК, ЧТО Я ДОЛЖЕН СДЕЛАТЬ ВМЕСТО?)
+0

Это хороший способ, за исключением, конечно, что нет смысла индексировать ваши поля и события до нуля. Поля по умолчанию являются пустыми, как и поле поддержки за событием. –

+0

@ KrisVandermotten Это просто старая привычка, от которой я не могу избавиться. Даже не осознавал, что это там, пока вы не указали это. :) – mishan

ответ

4
  1. Это хороший способ сделать это.
  2. Нет, вы не должны использовать другой способ.

Дополнительные предложения:

снова Думая об этом, я бы улучшить вашу архитектуру, вводя дополнительный уровень иерархии, где CanExecute() и Execute() являются abstract. Из этого класса выведите свой командный класс, который вызывает делегатов.

Таким образом, вы можете позже решить, хотите ли вы предоставить свою логику для ваших беспараметрических команд через делегатов или путем подкласса базового командного класса.

+0

Я не был уверен, что я делаю это правильно. Береженого Бог бережет. Спасибо за быстрый ответ и предложение, я собираюсь использовать делегатов на этот раз - мне лучше, но я буду помнить об этом. – mishan

3

Я не уверен, в чем ваша проблема. Обычно игнорируются параметры в интерфейсе ICommand.

Если вы действительно хотите, чтобы методы CanExecute и Execute не имели параметров, вы можете реализовать интерфейс явно (а не неявно). В ICommand методы все еще будет существовать, но тех, кто ищет на свой объект с внешней стороны, они не смогут увидеть эти методы:

bool ICommand.CanExecute(object parameter) { this.CanExecute(); } 

public bool CanExecute() 
{ 
    //do work 
} 

Вы, по существу, скрывая интерфейс реализации внешних. Если кто-то хочет напрямую вызвать метод CanExecute из интерфейса, им нужно будет ввести cast для ICommand, чтобы сделать это.Вы действительно ничего не получаете в этом, но если вы обеспокоены тем, как ваш класс смотрит на внешних разработчиков (например, вы разрабатываете API), то это может сделать его немного чище, поскольку вы даете им знать вам не нужны никакие параметры.

+0

Я просто не был уверен, что я делаю это правильно, поэтому я спросил. Я новичок в разработке WP8, и я просто изучаю, как это сделать. Есть (буквально) тысячи учебных пособий в Интернете, но я не мог найти, правильно ли я думаю. – mishan

1

Я лично предпочитаю это так:

public class MyCommand : ICommand 
{ 
    private static bool True() { return true; } 

    private readonly Action _execute; 
    private Func<bool> _canExecute; 
    private Func<bool> _isVisible; 

    public event EventHandler IsVisibleChanged; 
    public event EventHandler CanExecuteChanged; 

    public MyCommand(Action execute, Func<bool> canExecute = null, Func<bool> isVisible = null) 
    { 
     _execute = execute; 
     _canExecute = canExecute ?? True; 
     _isVisible = isVisible ?? True; 
    } 

    public void Execute() 
    { 
     _execute(); 
    } 

    public Func<bool> CanExecute 
    { 
     set 
     { 
      _canExecute = value ?? True; 
      CanExecuteChanged(this, new EventArgs()); 
     } 
     get { return _canExecute; } 
    } 

    public Func<bool> IsVisible 
    { 
     set 
     { 
      _isVisible = value ?? True; 
      IsVisibleChanged(this, new EventArgs()); 
     } 
     get { return _isVisible; } 
    } 

    bool ICommand.CanExecute(object parameter) 
    { 
     return CanExecute(); 
    } 

    void ICommand.Execute(object parameter) 
    { 
     Execute(); 
    } 
} 

Однако, поскольку делегаты, как правило, не меняются, я предпочитаю непреложную версию:

[ImmutableObject(true)] 
public class MyImmutableCommand : ICommand 
{ 
    private static bool True() { return true; } 

    private readonly Action _execute; 
    private readonly Func<bool> _canExecute; 
    private readonly Func<bool> _isVisible; 

    [Obsolete("Will not be invoked, because the implementation never changes.")] 
    public event EventHandler CanExecuteChanged; 

    public MyImmutableCommand(Action execute, Func<bool> canExecute = null, Func<bool> isVisible = null) 
    { 
     _execute = execute; 
     _canExecute = canExecute ?? True; 
     _isVisible = isVisible ?? True; 
    } 

    public bool CanExecute() 
    { 
     return _canExecute(); 
    } 

    public bool IsVisible() 
    { 
     return _isVisible(); 
    } 

    public void Execute() 
    { 
     _execute(); 
    } 

    bool ICommand.CanExecute(object parameter) 
    { 
     return CanExecute(); 
    } 

    void ICommand.Execute(object parameter) 
    { 
     Execute(); 
    } 
} 
Смежные вопросы