Как реализовать отмену / повтор в приложении MVVM? - PullRequest
5 голосов
/ 25 августа 2010

Я работаю над приложением Silverlight LoB, дизайнеры которого хотят иметь интерфейс с вкладками, аналогичный интерфейсу Visual Studio (вероятно, мы будем использовать элементы управления Telerik Rad для закрепления вкладок).Сделав прототип, интерфейс работает хорошо до сих пор, но у меня возникают проблемы с размышлениями о том, как реализовать функциональность отмены / возврата в проекте MVVM.

Функциональные возможности отмены / повтора должны:

  1. При отмене / возврате восстановить состояние пользовательского интерфейса, то есть вернуть фокус, выделение и т. Д. Элементам управления (таким кактекстовое поле), из которого произошли изменения.
  2. Наличие стека отмен / повторов для каждого вида

Как правило, я бы использовал шаблон команды, но не уверен, какпримените это с MVVM.

Я использовал командование и привязку, чтобы получить идеализированную слабую связь представлений и моделей представлений, но это усложняет отмену / повтор, так как модель представления не имеет никакой концепциипредставление и состояние представления при получении команды или изменении связанного свойства.Кажется, мне нужен какой-то сервис отслеживания, представление которого активно всякий раз, когда пользователь выполняет какое-то отменяемое действие и получает состояние для последующего восстановления.

Есть ли консенсус в отношении того, что является наилучшей практикой для выполнения отмены / повтора в MVVM?Я с интересом посмотрел на то, как Даниэль Воган делает это в своем проекте Calcium;Очевидно, Blend был написан с использованием шаблона MVVM, и он ведет себя так, как я хочу, чтобы мое приложение, было бы здорово, если бы MS объяснила, как они это сделали!

Ответы [ 2 ]

2 голосов
/ 25 августа 2010

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

В наиболее удачных системах отмены, которые мы использовали, ранее разрешалось вложение IUndoableCommandобъекты.Эти составные команды объединяются в одно пользовательское действие (такое действие, которое вы ожидаете увидеть в меню «Отменить»).

Я отмечаю, что вы упомянули использование отмены между представлениями ... Это выглядит как необычное поведение длямультиформное приложение.Обычно отмена выполняется только в отдельных элементах управления и для любых операций перетаскивания.Исключениями обычно являются графические интерфейсы (не основанные на формах).Изменение формы во время отмены будет эквивалентно переключению MS Word на другой документ и продолжению отмены ... довольно неприятно для конечного пользователя.Возможно, вам захочется, чтобы ребята из пользовательского интерфейса переосмыслили этот аспект дизайна.Только мои 2 цента.

Надеюсь, это поможет.

1 голос
/ 21 июня 2011

@ JamesCo,

Я реализовал отмену / повтор для приложения WPF и в итоге опубликовал свой код отмены / возврата в http://muf.codeplex.com/. Вы также можете получить его через NuGet. Просто найдите «MUF» или «Monitored Undo Framework». Включает поддержку Silverlight 4.0, а также .NET 3.5, 4.0 и WP7.

Мое приложение WPF также использовало MVVM и, в некоторых случаях, позволяло отменять такие вещи, как изменения выбора. Я также отслеживал активную «страницу», отображаемую в кадре WPF, чтобы пользователь был перемещен обратно на страницу, где должно применяться действие отмены.

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

Что касается изоляции изменений для каждого представления, библиотека позволяет хранить отдельный стек действий отмены / возврата для каждого «документа» или «контейнера». Вы просто передаете ссылку на контейнер, чтобы получить связанный стек отмены / повтора.

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

Комментарии и вопросы приветствуются на сайте codeplex (http://muf.codeplex.com/).. Там же вы найдете полную документацию и примеры приложений.

...