MVVM и Stateful команды - хорошая или плохая идея? - PullRequest
1 голос
/ 24 августа 2009

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

Я использую фреймворк Cinch MVVM от Sacha Barber, который включает класс SimpleCommand Марлона Греча.

Единственное, чего нет у этого класса, а у некоторых других альтернатив это свойство Text, которое обычно можно использовать для привязки элементов пользовательского интерфейса к «Заголовку» командной операции. Следовательно, я пишу расширение для этого класса, которое предоставляет свойство Text.

Теперь я столкнулся с примером использования, когда я использую команду для переключения подключения к устройству. Я мог реализовать это множеством разных способов (не всегда - это программное обеспечение!). Одним из способов было бы выставить несколько объектов команд из моей ViewModel - один для «Disconnect» и один для «Connect»; пусть модель представления предоставляет свойство, которое указывает состояние соединения (IsConnected), и имеет представление, условно привязанное либо к команде Connect, либо к команде Disconnect. Моя реакция на эту опцию, однако, ... гадость!

Вместо этого я изначально начал изучать не только предоставление свойства Text, но и наличие объекта команды, реализующего INotifyPropertyChanged, так что свойство view может динамически изменяться с помощью viewmodel на «Connect» или «Disconnect» в зависимости от состояния системы. Делая это, я могу избежать нескольких команд и просто выставить один объект команды ToggleConnection.

Однако, начиная с этого пути, мне приходит в голову, что могут быть другие варианты этого шаблона, в соответствии с которыми пользовательский интерфейс должен быть изменен в соответствии с состоянием команды. Например, помимо изменения текста команды в соответствии с состоянием соединения, у вас могут быть места, где значок должен меняться в зависимости от состояния соединения. Итак, я начал писать класс Stateful, который реализует INotifyPropertyChanged и предоставляет два свойства - «Текст» и «Состояние». Я сделал класс универсальным, чтобы тип State мог быть определен пользователем (я обычно предпочитаю не использовать «object» там, где его можно избежать).

Вопрос, который у меня возникает ... Как вы думаете, это хорошая или плохая идея? Это может отличаться от первоначального намерения / замысла команд; Из того, что я видел, в целом может быть так, что объекты команд были предназначены для того, чтобы не сохранять состояния, поскольку они являются «глаголами» системы. С маршрутизированными командами, если я правильно понимаю вещи, обычно ожидается, что только цель команды будет иметь состояние. Тем более что одна и та же команда может быть перенаправлена ​​на разные обработчики в зависимости от того, где объявлены привязки команд.

Итак, я думаю, что по крайней мере с перенаправленными командами состояние не имело бы смысла.

Однако я не имею дело с маршрутизируемыми командами - я специально имею дело с командами MVVM. В этом случае в принципе отсутствует условная маршрутизация команд - представления MVVM привязываются непосредственно к объектам команд конкретной модели представления, и они выполняют и могут выполнять обработчики.

В этом случае имеет ли смысл?

Я приложил копию соответствующего кода на случай, если он будет полезен / интересен.

Спасибо, Фил

Ответы [ 2 ]

1 голос
/ 24 августа 2009

Вам решать, с чем, по вашему мнению, будет легче работать.

Лично я не ставлю свойство .Text на мои команды просто потому, что не получаю повторного использования этих команд. Это отличается от команд RoutedUIC, предоставленных в платформе (или аналогичных пользовательских статических команд), потому что они используются везде, и если перевод «Выход» изменится в этой команде, это будет отражено во всем приложении. Это не так в вашем примере - все будет одноразовым.

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

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

Во всяком случае, это немного многословно ... отрывок "сделай все, что удобно".

0 голосов
/ 25 августа 2009

Как говорилось в последнем плакате: «Все, что вам удобно».

В моем случае я обычно использую что-то вроде DelegateCommand . Если мне нужно привязать некоторые данные, я привязываюсь к виртуальной машине. Когда команда выполняется, она выполняется в моей виртуальной машине (через делегат, предоставленный DelegateCommand в init). Затем исполняемый делегат может / не может запустить некоторый повторно используемый код для удовлетворения команды.

Звучит так, будто вы хотите использовать Команду в качестве собственной виртуальной машины. Я никогда не думал делать это раньше себя, но если вам это нравится, сделайте это! :)

...