Переключение между режимом просмотра и режимом редактирования в MVVM?
Я новичок в MVVM и я решил двигаться дальше и начать принимать его в моих будущих проектах.
Я прочитал этот вопрос и ответ, но я не знаю, как это будет реализовано с помощью MVVM.
Я хочу, чтобы все мнения, в моем проекте есть 2 режима, режим редактирования и режим просмотра.
Я не хочу, чтобы пользователь по умолчанию видел текстовые поля для всех полей, я скорее хочу, чтобы они видели TextBlocks (или установили все TextBoxe
s ' as IsReadOnly
свойство true (через стиль и т. д. ты мне скажи..).
когда пользователь открывает объект, он обычно должен быть TextBlocks, Labels (или readonly TextBoxes) и т. д., и если он нажимает "редактировать" (если у него есть разрешение), он должен перейти в режим редактирования, и все метки полей должны быть инвертированы в текстовые поля (RichTextBoxes и т. д., ComboBoxes или любые другие редактируемые поля, которые не являются просто метками).
Я уверен, что я не единственный, кто имеет эту проблему, я хотел бы услышать от экспертов, что такое наиболее эффективный способ переключения между этими режимами в чистом MVVM и является ли это общим для объявления двух отдельных представлений для него.
пожалуйста, обратитесь ко мне в хорошую статью, которая объясняет, как это сделать (может быть, это делается визуальным состоянием?? IDK).
обновление
Я хочу знать, что, а не как, мой вопрос касается шаблона, и это должен ли я отделить режим редактирования
из режима просмотра в V или VM?
Поэтому, пожалуйста, подчеркните эту деталь в ваш ответ.
спасибо заранее.
5 ответов
использовать 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;
Я думаю об этом так: представление-это то, как оно выглядит, а ViewModel-как оно взаимодействует с пользователем. Поскольку интерфейс readonly имеет существенно различное поведение, чем интерфейс чтения / записи, то должны быть две разные модели представления.
теперь я создал Edit ViewModel, который унаследовал от display ViewModel, потому что я считал функциональность редактирования расширением функциональности отображения. Это работает для простого типа CRUD приложения, где пользователь непосредственно редактирует поля без большой бизнес-логики.
с другой стороны, если у вас есть более сложный бизнес-процесс (или рабочий процесс), который вы моделируете, то обычно способ управления информацией сильно отличается от того, как вы хотите ее просмотреть. Поэтому я бы вообще разделил две ViewModels, если бы это не было просто CRUD.
ChrisF это нормально, если вы хотите идти по пути IsReadOnly. Если вы хотите пройти маршрут TextBlock-to-TextBox, наиболее эффективным способом является элемент управления, который переключает свой шаблон через триггеры на основе значения свойства IsInEditMode или IsInViewModel.
Viewmodel: я бы определенно сохранил только одну viewmodel со свойством ViewMode, как описано в ответе ChrisF. Отдельные ViewModels были бы просто неэлегантными.
View: как я вижу, у вас есть по крайней мере три варианта, с различными плюсами и минусами.
просто прочитайте все элементы управления, как предложено в ответе ChrisF. Плюсы: простейшая вещь. Минусы: это уродливый UI по моему скромному мнению.
создать seaparate дисплей и элементы управления в отдельных контейнерах. Свяжите видимость контейнеров с ViewMode. Плюсы: Более приятный пользовательский интерфейс может быть предоставлен здесь. Вы даже можете анимировать переходы от одного к другому. Минусы: удваивает количество элементов управления (может повредить производительность для очень больших окон). Позиционирование элементов управления внутри двух контейнеров в точно таких же позициях пикселей может стать немного нетривиальным в жидком пользовательском интерфейсе.
для каждого редактирования элемент управления в xaml расположите элемент управления display прямо над ним. Привязать видимость к свойству ViewMode. Плюсы: нет дублирования меток, по крайней мере, так немного быстрее. Минусы:сложнее получить анимацию и другие настройки просмотра.
Edit: ввиду предоставленного разъяснения я решил заменить предыдущий ответ, поскольку он в значительной степени касался того, как, а не что.
во-первых, я бы реализовал абстрактный базовый класс для моих моделей представления, которые реализовали IEditableObject
и выставлены соответствующие команды для BeginEdit
, EndEdit
и CancelEdit
. Возможно, фактические реализации для этих трех методов должны быть до производных классов, но команды могут жить в базовом классе.
при таком подходе EndEdit
обновляет модель текущими значениями свойств в модели представления.
Я бы также реализовать логическое IsEditing
свойство в базовом классе, для использования в триггерах данных, так что если я хочу переключаться между режимами без (скажем) открытия модального диалога, я могу просто сделать это в стиле.
что касается визуального дизайна интерфейса, я считаю, что представление только для чтения-это просто вид редактирования с элементами управления только для чтения, который в первую очередь привлекает программистов. Вообще говоря, если вы просто представляете объект пользователю, цель этой презентации-предоставить пользователю информативное, ясное и интуитивное представление информации в этом объекте. Если вы позволяете пользователю редактировать объект, цель этой презентации - сделать задачу изменения всех редактируемых свойств объекта максимально простой и понятной.
это два совершенно разных набора целей. Например, в то время как пол, рост и вес человека могут быть важными частями информации для приложения, чтобы собрать, это, вероятно, не все, что важно чтобы система представляла эту информацию пользователю в большинстве контекстов. Это кажется очень естественным, если у вас в голове есть режим редактирования, как и режим отображения. Но если вы размещаете потребности пользователя, а не программиста, спереди и в центре, это может быть вообще неправильно.