MVVM Передача данных в диалоговое окно View Model - PullRequest
15 голосов
/ 03 марта 2010

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

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

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

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

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

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

Спасибо Matt

Ответы [ 3 ]

2 голосов
/ 03 марта 2010

Возможно, я бы сделал это следующим образом:

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

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

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

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

1 голос
/ 03 марта 2010

В этой статье из codeproject показан элемент управления WPF Dialog, который делает именно то, что вам нужно. Причина, по которой эта реализация необходима, заключается в том, что вы не можете поместить Window в визуальное дерево любого другого элемента управления. Это означает, что из коробки 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 , как показано в этом сообщении )

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

0 голосов
/ 07 марта 2010

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

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

...