2011-02-06 3 views
9

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

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

Я хочу, чтобы все виды в моем проекте имели 2 режима, режим редактирования и режим просмотра.
Я не хочу, чтобы пользователь по умолчанию видел TextBoxes для всех полей, я скорее хочу, чтобы они увидели TextBlocks (или установили для всех TextBoxe s как IsReadOnly свойство true (через стиль и т. Д. Вы мне скажите ..) .

Когда пользователь открывает объект, он обычно должен быть TextBlocks, Ярлыки (или только текстовые поля) и т. Д., И если он нажимает «Изменить» (если у него есть разрешение), он должен перейти в режим редактирования, и все метки полей должны быть инвертированы в TextBoxes (RichTextBoxes и т. д., ComboBoxes или любые другие редактируемые поля, которые не являются только метками).

Я уверен, что я не единственный, у кого есть эта проблема, я хотел бы услышать от экспертов, что является наиболее эффективным способом переключения b между этими режимами в чистом MVVM и является ли это общим объявлением для него двух отдельных представлений.

Пожалуйста, обратитесь к хорошей статье, в которой объясняется, как это сделать (возможно, это делается визуальным состоянием IDK).

UPDATE
Я хочу знать, что вместо того, КАК, на мой вопрос о шаблоне, и я должен отделить Edit Mode от View Mode либо на V или VM? Поэтому, пожалуйста, подчеркните эту деталь в своем ответе.

Заранее спасибо.

ответ

10

Используйте IsReadOnly свойство для текстовых полей и связать, что свойство «режима редактирования»:

<TextBox .... IsReadOnly={Binding IsViewMode} ... /> 

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

public bool IsViewMode 
{ 
    get { return _IsViewMode; } 
    set 
    { 
     _IsViewMode= value; 
     // Call NotifyPropertyChanged when the source property is updated. 
     NotifyPropertyChanged("IsViewMode"); 
    } 
} 

IsViewMode по умолчанию для true и включается до false, когда пользователь нажимает «редактировать». Связывание моментально сделает все текстовые поля доступными для редактирования.

Вы можете сделать то же самое для других элементов управления - хотя это будет IsEnabled свойство, с которым вам нужно привязываться в этих случаях - хотя вы бы не выбрали элементы управления.

Чтобы поменять текстовые блоки и элементы управления вам нужно иметь оба управления делить то же место в сетке и их видимость контролируемых IsViewMode собственности через пару преобразователей:

<TextBlock Grid.Row="1" Grid.Column="2" ... 
      Visiblity={Binding IsViewMode, Converter=DirectConverter} ... /> 
<ComboBox Grid.Row="1" Grid.Column="2" ... 
      Visiblity={Binding IsViewMode, Converter=InvertedConverter} ... /> 

Прямым преобразователь:

return IsViewMode ? Visibility.Visible : Visibility.Collapsed; 

перевернутой конвертер:

return IsViewMode ? Visibility.Collapsed : Visibility.Visible; 
+0

А как насчет других полей? Я сказал, что хочу, чтобы некоторые поля инвертировались в DropDown, некоторые - на слайдер, а некоторые - на сборщик дат, тогда как в режиме просмотра все они были просто текстовыми блоками/ярлыками? И это очень важная часть для меня. – Shimmy

+0

@Shimmy - извините, я пропустил этот бит (не знаю почему). Вы можете сделать то же самое для ComboBoxes, но это может быть свойство IsEnabled, с которым вам нужно привязать. – ChrisF

+0

Итак, вы в основном говорите, что я должен сделать общий вид для режимов редактирования/просмотра, имея все элементы управления, объявленные рядом с другим параметром, который элемент управления IsReadOnly или Visibility для IsViewMode на виртуальной машине (с использованием конвертера BooleanToVisibility для скрытия элементов управления), это так? ** Я добавил некоторое содержание к моему вопросу. ** – Shimmy

2

Viewmodel: Я бы определенно оставил только одну модель представления с свойством ViewMode, как описано в ответе ChrisF. Отдельные ViewModels будут просто неэлегантными.

View: Как я вижу, у вас есть как минимум три варианта, с различными плюсами и минусами.

  1. Просто прочитайте все элементы управления, как это предлагается в ответе ChrisF. Плюсы: Простейшая вещь. Минусы: Это уродливый интерфейс в моем скромном мнении.

  2. Создайте морские дисплеи и отредактируйте элементы управления в отдельных контейнерах. Свяжите видимость контейнеров с ViewMode. Плюсы: Более приятный опыт можно получить здесь. Вы можете даже оживить переходы от одного к другому. Минусы: удваивает количество элементов управления (может повредить производительность для очень больших окон). Позиционирование элементов управления внутри двух контейнеров в одинаковых положениях пикселей может стать немного нетривиальным в жидкости ui.

  3. Для каждого элемента управления редактированием в xaml расположите элемент управления дисплеем прямо над ним. Связать видимость с свойством ViewMode. Плюсы: Нет дублирования управления ярлыками, по крайней мере, так немного быстрее. Минусы: Сложнее получить анимационный материал и другие настройки.

Редактировать: Ввиду предоставленного пояснения я решил заменить предыдущий ответ, поскольку он в значительной степени в значительной степени касается того, как, а не того, что.

+0

Я добавил некоторое содержание к моему вопросу. Я бы так не сказал. Я ненавижу, что ViewModel знает, что есть перечисление Видимости ... Я хотел бы следовать [Ответ ChrisF] (http://stackoverflow.com/questions/4917047/switching-between-view-mode-and-edit-mode-in -mvvm/4917104 # 4917104) с использованием конвертеров BooleanToVisibilit/BooleanFlagSwitch и т. д. Я только что получил ответ, что режим просмотра и режим редактирования НЕ должны быть разделены в любом случае. – Shimmy

+0

@Shimmy: Я думаю, что пока режим отображения и редактирования должен принадлежать к одному классу вида и привязан к одной и той же модели представления, элементы управления для них должны быть отделены для лучшего опыта работы с ui. Я изменил ответ, чтобы отразить то же самое. – anshul

+1

Нет ничего плохого в модели представления, зная, что есть такая вещь, как видимость. –

3

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

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

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

+0

Точно, я говорю о CRUD. Как я уже сказал, я новичок в MVVM и хочу его изучить. Можете ли вы сослаться на хорошую статью о том, как реализовать CRUD-приложение MVVM? Моя проблема - это также переходы между разные взгляды – Shimmy

+0

Точно, я говорю о CRUD. Как я уже сказал, я новичок в MVVM и хочу его изучить. Можете ли вы направить меня к хорошей статье о том, как реализовать CRUD-приложение MVVM? ** Моя основная Проблема также является переходом между различными представлениями.** – Shimmy

+1

@Shimmy - Я предлагаю [Advanced MVVM] (http://joshsmithonwpf.wordpress.com/advanced-mvvm/) Джошем Смитом. Он короткий, но очень информативный, и вы можете получить исходный код. –

3

Ответ ChrisF в порядке, если вы хотите пройти маршрут IsReadOnly. Однако, если вы хотите идти по маршруту TextBlock-to-TextBox, наиболее эффективным способом является элемент управления, который переключает свой шаблон через триггеры на основе значения свойства IsInEditMode или IsInViewModel.

2

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

В этом подходе EndEdit обновляет модель с текущими значениями свойств в модели представления.

Я бы также реализовал свойство boolean IsEditing в базовом классе для использования в триггерах данных, чтобы, если я хочу переключаться между режимами без (скажем) открытия модального диалога, я могу просто сделать это в стиле ,

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

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

Смежные вопросы