MVVM Передача данных в диалоговое окно Просмотр модели

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

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

Я понимаю, что кнопка может быть привязана к команде в списке ViewModel, но отсюда как мне создать экземпляр редактора foobar?

1) Должен ли я отправить сообщение обратно в представление, которое откроет диалоговое окно? Если это так, разве это не побеждает цель иметь команду?

2) Как foobar передается в ViewModel для редактора? Если это его конструктор, не затрудняет ли объявление ViewModel в XAML?

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

Спасибо Matt

Ответы

Ответ 1

Я бы сделал это следующим образом:

  • Команда, прикрепленная к кнопке редактирования, запускает диалог редактирования, создавая для него пользовательскую ViewModel (VM). Сама команда должна быть, возможно, либо в списке VM, либо в модели (не совсем уверен).
  • Диалог редактирования Foobar VM получает ссылку на Foobar в своем конструкторе.
  • foobar клонируется и клоун редактируется.
  • Как только пользователь нажимает OK в диалоговом окне редактирования foobar, значения клона записываются обратно в исходный foobar в виртуальной машине (и диалог закрывается).

Потребность в клоне исходит из того, что пользователь не хочет видеть изменения в списке foobar, пока не примет изменения в диалоговом окне редактирования. Если, однако, онлайн-редактирование в порядке, клон не нужен.

Изменения распространяются автоматически.

PS: хотя я сторонник MVVM, я не уверен, что мое решение является ортодоксальным с чистой точки зрения MVVM.

Ответ 2

В этой статье из codeproject показан элемент управления WPF Dialog, который делает именно то, что вам нужно. Причина, по которой эта реализация необходима, заключается в том, что вы не можете поместить окно внутри визуального дерева любого другого элемента управления. Это означает, что из окна WPF не разрешается создавать диалог внутри окна. Поэтому в приведенной выше статье создается подкласс ContentControl, который создает окно.

В любом случае вы помещаете это в свой FooBarList View

<dialog:Dialog Content="{Binding Path=DialogViewModel}" /> 

Вы убедитесь, что у вас есть что-то подобное в словаре ресурсов где-то:

<Style TargetType="{x:Type dialog:Dialog}">
 <Style.Triggers>
  <Trigger Property="HasContent" Value="True">
   <Setter Property="Showing" Value="True" />
  </Trigger>
 </Style.Triggers>
</Style>

и просто напишите что-нибудь вроде этого (для работы WPF вам нужно реализовать INotifyPropertyChanged):

public Class FooBarListViewModel
{
  IList<FooBar> FooBarList {get;set;}
  FooBar SelectedFooBar {get;set;}
  ViewModelBase DialogViewModel {get;set;}

  public EditFooBar(object param)
  {
    DialogViewModel = FooBar;
  }
}

Чтобы связать View для редактирования FooBar в FooBar ViewModel, просто сделайте что-нибудь подобное (желательно в Application.Resources, чтобы оно было глобальным)

<DataTemplate DataType={x:Type vm:FooBarViewModel}>
  <vw:FooBarView/>
</DataTemplate>

(Или необязательно: используйте конвертер IValueConverter для преобразования вашего представления из ViewModel как показано в этом сообщении)

И тогда вы настроены. Может показаться, что много, но это действительно освобождает вас.

Ответ 3

Отсутствует контроллер, который отвечает за рабочий процесс ViewModels. Контроллер создает ViewModels и передает необходимые данные между ViewModels.

Проект Проект WPF Application Framework (WAF) содержит примеры приложений, которые показывают, как это может работать.