MVVM Передача данных в диалоговое окно View Model

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

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

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

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

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

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

Спасибо Мэтт


person Matt    schedule 02.03.2010    source источник


Ответы (3)


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

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

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

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

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

person Vlad    schedule 02.03.2010

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

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

(Или, необязательно: используйте IValueConverter для преобразования, чтобы получить представление из ViewModel как этот пост показывает)

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

person Jose    schedule 03.03.2010
comment
Это интересный подход. Глядя на пример проекта, я задаюсь вопросом, не буду ли я уязвлен, потеряв некоторые функции обычного окна (изменение размера, немодальное и т. Д.). Я начинаю думать, что, возможно, стоит подумать о дизайне, который вообще не требует сложных диалогов - и, возможно, вместо этого имеет приложение MDI. Что вы думаете об этом? - person Matt; 04.03.2010

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

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

person jbe    schedule 07.03.2010