2016-03-10 4 views
8

Очень часто реализация RelayCommand кажется, включает в себя следующие строки:Является ли общая реализация RelayCommand нарушением шаблона MVVM?

public event EventHandler CanExecuteChanged 
{ 
    add 
    { 
     CommandManager.RequerySuggested += value; 
    } 
    remove 
    { 
     CommandManager.RequerySuggested -= value; 
    } 
} 

Это кажется очень ущербным для меня, потому что CommandManager является компонентом WPF и обычно мои команды находятся в классе ViewModel. Поскольку viewmodel не должен знать точку зрения и должен работать с различными структурами и т. Д., Это кажется мне очень странным. Например, эта реализация будет невозможна, если вы выделите свою модель просмотра в дополнительном проекте, который не знает пространство имен WPF (например, PCL).

Является ли эта реализация нарушением шаблона MVVM?
Или вы можете разместить RelayCommand на ваш взгляд?
Если это действительно ошибочно, существует ли передовая практика, которая решает эту проблему?

+0

ваш viewmodel для вашего зрения, просто не ссылаясь на него. так что все в порядке. – blindmeis

+0

@blindmeis Используя компонент вида, он действительно ссылается на него.Будет довольно ясно, если вы попытаетесь использовать эту реализацию RelayCommand в приложении, отличном от wpf. –

+0

Я не думаю, что вы будете использовать viemodel для wpf в другом приложении, отличном от wpf :) Основная цель - тестирование без интерфейса, и это работает. – blindmeis

ответ

3

Это простая и быстрая обработка &, в основном используемая только для учебных случаев, которые не привязывают учебное пособие к определенной структуре MVVM, но действуют как универсальный учебник по MVVM по-своему.

Этот подход, отличный от жесткой связи, имеет ряд других недостатков.

Когда вызывается метод CommandManager.InvalidateRequerySuggested(), вызывается метод CanExecute каждой команды. Если в приложении есть 100 команд, это может серьезно повлиять на производительность вашего приложения WPF.

Я лично всегда предлагаю использовать зрелую MVVM Framework (Призма - моя любимая для LoB-приложений). Там команды обычно не реализуют его таким образом, но вы вызываете MyCommand.OnCanExecuteChanged() (в случае Prism), чтобы вызвать CanExecute валидация для одна команда.

Если у вас есть составные или несколько команд, которые зависят друг от друга, вы привязываете их самостоятельно в коде, то есть, сохраняя список связанных команд внутри используемого представления и прокручивая его или регистрируя их методы OnCanExecuteChanged() для многоадресной рассылки делегировать и называть это вместо этого.

Является ли эта реализация нарушением шаблона MVVM?

Технически да.

Возможно, вы каким-либо образом разместите RelayCommand?

Не совсем, хотя вы можете быть в состоянии абстрагировать с внешним завода, это не кажется, имеет смысл (см выше вопрос)

Если это действительно недостатки, есть передовая практика, которая решает эту проблему?

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