Как и где ICommands вписываются в общий шаблон WPF MVVM? - PullRequest
3 голосов
/ 01 марта 2012

Я пытаюсь узнать, как использовать команды WPF и как они вписываются в шаблон MVVM.Я понимаю, что некоторые элементы управления, такие как кнопка или меню, имеют свойство Command, которое при установке на экземпляр класса ICommand соединяет кнопку с этой командой.Как только это будет установлено, кнопка будет затем отключаться и включаться с помощью события CanExecuteChanged команды, а нажатие на элемент управления вызовет метод Execute команды.

Однако, где должен жить экземпляр каждой ICommand?Я видел различные варианты в уроках, и я не уверен, что это правильно.В некоторых примерах создается статический класс «ApplicationCommands», и экземпляру каждой команды назначается статическое свойство этого класса.В других примерах я видел команды, установленные как свойства ViewModel, а также в других самих View / Window.Какое место предпочтительнее для экземпляров команд?

Кроме того, как команда относится к представлению, модели просмотра или модели?Какой из этих компонентов команда должна знать и / или манипулировать?Что должно произойти при выполнении команды?Должен ли он вызывать какой-либо метод модели, который затем сообщает об изменениях обратно в модель представления / представления?Или команда должна общаться с моделью через метод View Model?

Ответы [ 2 ]

1 голос
/ 01 марта 2012

В некоторых примерах создается статический класс «ApplicationCommands», и экземпляру каждой команды назначается статическое свойство этого класса

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

видимые команды, установленные как свойства ViewModel и других окон самого View / Window.

Если команда что-то делает с данными, то ViewModel - хорошее местодля этого.Если команде не нужно ничего делать с данными, поместите ее в код позади View (поскольку она не имеет ничего общего с ViewModel и вам не нужно загрязнять ViewModel этим).Интересный случай, когда вы делаете что-то вроде всплывающего диалогового окна в ответ на нажатие клавиши, и вам нужно передать текущий выбранный элемент сетки в диалоговое окно - куда должна идти команда?В этом случае я бы поместил его в код за представлением, поскольку нет веской причины помещать его во ViewModel - выбранный элемент может быть извлечен из ViewModel представлением, если необходимо.

Много разЯ видел команды, которые без нужды вводили в ViewModel просто потому, что люди думали, что это единственный способ сделать это.Эмпирическое правило, которое я использую: если оно выполняет работу, связанную с пользовательским интерфейсом, оно входит в код позади представления.Если он выполняет работу с данными, он может перейти в ViewModel.Если он делает смесь, то рассмотрите возможность разделения функциональности как по View, так и по ViewModel.

Какой из этих компонентов команда должна знать и / или манипулировать?

Только те, о которых он должен знать.Доступ к таким компонентам, как Модель, из ViewModel должен осуществляться через правильно определенное свойство или функцию, которая возвращает интерфейс, чтобы избежать тесной связи.

Если он вызывает некоторый метод Модели, который затемпередает изменения обратно в View Model / View?

Нет проблем с командой доступа к модели из ViewModel.Команда может обновить свойства в ViewModel или Model, и с помощью магии привязки данных и уведомлений о свойствах эти обновления могут быть отражены обратно в пользовательском интерфейсе.

1 голос
/ 01 марта 2012

Подход со статическими командами обычно используется с RoutedCommands или командами, которые имеют широкое применение, которое не связано с состоянием какого-либо конкретного объекта. Если вы используете динамические реализации ICommand, которые передают свои методы в конструктор, они обычно являются экземплярами ViewModel, к которому относится эта команда.

Эти команды могут действовать в ViewModel и Model, как вы сами это делаете, я часто просто вызываю соответствующий метод на виртуальной машине из Execute команды, чтобы сохранить код инициализации команды кратким.

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

...