Каков принятый шаблон для команд WPF в MVVM? - PullRequest
6 голосов
/ 15 декабря 2009

Я работаю над приложением WPF и довольно хорошо понимаю шаблон команд, но обнаружил, что существует несколько различных реализаций шаблона команд для MVVM. В его образце приложения WPF есть реализация Джоша Смита, DelegateCommand от Prism и реализация CommandBindings.

Мой вопрос: какова общепринятая лучшая практика использования команд с MVVM? Мое приложение использует Prism, поэтому DelegateCommand доступен для нас.

Разработчики в моей команде спорят о том, какой подход "лучший". Некоторым не нравятся многочисленные файлы .cs, сгенерированные для каждой команды, другие предпочитают, чтобы все было подключено через CommandBindings. Я в недоумении. Кто-нибудь может пролить свет?

Ответы [ 2 ]

3 голосов
/ 15 декабря 2009

Ну, я думаю, что нет решения .

CommandBindings не так легко тестируются и представляют зависимость от классов WPF в ViewModel, что не очень хорошо. Поэтому я бы не стал их использовать.

И DelegateCommand, и CommandSinkCommand (решение Джоша Смита) являются хорошими способами IMO. Они на самом деле не отличаются, и ни один из них не превосходит другого. Хотя я заметил, что версия CommandSink не всегда работает, когда маршрутизация команд усложняется (особенно когда используются шаблоны данных).

Вы даже можете объединить их: используйте DelegateCommand и дополнительно используйте версию JoshSmith - так что вы можете объединить преимущества обоих. Единственное, что вам нужно, это несколько вспомогательных классов, которые не так сложно реализовать.

Гораздо важнее согласованность в вашем приложении: если вы решили, что вы хотите использовать, вы должны следовать этому примеру во всем приложении.

2 голосов
/ 02 июня 2010

Два вопроса для рассмотрения:

Команды, предоставляемые различными средами MVVM, такими как CommandSinkCommand или SimpleCommand (из Cinch) и т. Д., Работают как обычные ICommands. В частности, обработчик CanExecute оценивается всякий раз, когда WPF считает, что что-то произошло, что может вызвать изменение пользовательского интерфейса. Вы также можете вручную форсировать это через CommandManager.InvalidateRequerySuggested().

В отличие от этого, DelegateCommands <> из Prism не вызывают обработчик CanExecute, если вы вручную не вызовете RaiseCanExecuteChanged() для команды. Если вы хотите изменить это так, чтобы оно также срабатывало, когда команды обычно запрашиваются, см. Код в http://compositewpf.codeplex.com/Thread/View.aspx?ThreadId=47338

EDIT:

Второй момент: команды сред MVVM обычно принимают объект в качестве параметра команды. Напротив, DelegateCommands <> из Prism более строго типизированы (хотя вы, конечно, могли бы иметь DelegateCommands, если хотите).

...