2013-05-13 4 views
12

Как мне делиться данными между несколькими ViewModels?
MVVM: Обмен данными между ViewModels

Например, в приложении используется класс Project.

public class Project : ModelBase 
{ 
    private string _projectName; 

    public string ProjectName 
    { 
     get { return _projectName; } 
     set 
     { 
      _projectName = value; 
      RaisePropertyChanged(() => ProjectName); 
     } 
    } 
} 

В нескольких приложениях ViewModels необходимо получить доступ к ActiveProject.
Каков наилучший способ поделиться проектом между ViewModels?

  • Посредник Pattern? (Сообщения)
  • Статического объект
  • Singleton шаблон (если да, то как?)

Я использовал сообщения раньше, но это нужно много codding. Для всех ViewModels я должен создать свойство ActiveProject, а также зарегистрировать мессенджер, чтобы его обновить.


Я использую рамки MVVM Light.
Любой пример кода был бы оценен.

+0

Является ли ваш 'ActiveProject' создан где-то одной из моделей? Если это так, обмен сообщениями, вероятно, будет лучшим (и это не *, что * verbose). Другой вариант заключается в том, чтобы вводить «ActiveProject» в каждую модель представления, которая ему нужна, при установке времени жизни «ActiveProject» в singleton в выбранном контейнере IoC - третий вариант, который вы предложили ... Но пока это в основном угадывает с моей стороны , –

+1

@ TrustMe-I'maDoctor Почему мы, WPF, всегда слишком усложняем? Не было бы намного проще сохранить это в классе 'App' как статическом свойстве? –

+0

@HighCore Это всегда вариант ... Статическое свойство чтения-записи неправильно меня раздражает, но слишком легко злоупотреблять. :) –

ответ

5

Я бы создал ViewModel, который будет выступать в роли родителя во всех моделях Project ViewModels. (Назовем это решение)

Решение ViewModel будет иметь свойство ActiveProject и наблюдаемую коллекцию проектов.

+0

, но тогда ... если у вас несколько режимов просмотра для одного вида, как вы связываете это совместное свойство? – inside

+0

@inside - существует одна топовая модель, которая назначается DataContext View. Другие модели представлений - это свойства этой модели верхнего вида и могут быть связаны, указав путь привязки относительно модели верхнего вида –

+2

. Я решил ее немного по-другому. У меня есть несколько режимов просмотра, в которых все имеют один и тот же класс ViewModelBase, в ViewModelBase у меня есть Singleton из списка «Projects», а затем в моем представлении я просто указываю путь привязки как childVM.Projects, поэтому не имеет значения, какой vm он есть, они будут все они имеют один и тот же экземпляр проектов. Это позволило мне иметь несколько режимов просмотра в DataContext, и нет никакой двусмысленности. – inside

1

У вас может быть статическая коллекция, которую ваша модель представления заполняет, прежде чем перейти к новой модели представления. Модель целевого представления может затем извлечь данные из своего конструктора.

Например, ViewModel1 (VM1) создаст проект и заполнит его. Затем VM1 помещает проект в осколок, статическую, коллекцию. Затем VM1 перейдет к другой модели представления (VM2). В конструкторе VM2 вы отправитесь в коллекцию и получите проект, размещенный там VM1.

Если вы использовали словарь пар ключ-значение, он также позволит вам делиться другими данными между моделями просмотра.

1

Singleton определенно поможет. Для реализации, если бы у меня был класс с именем Пользователь:

private static User mInstance; 

    private User() //constructor 
    { 
    } 

    public static User Instance 
    { 
     get 
     { 
      if (mInstance == null) 
       mInstance = new User(); 
      return mInstance; 
     } 
    } 
2

Я бы рекомендовал шаблон посредника. Я использовал EventAggregator для этого типа обмена сообщениями между виртуальными машинами до этого, и на самом деле это не так много.

+0

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

1

Не надо, не надо. Не используйте синглтоны таким образом в своем приложении MVVM. На самом деле класс Project должен быть моделью для ваших ViewModels. Просто передайте его в конструкторе vm. Если вам действительно нужно разделить один экземпляр класса Project в нескольких виртуальных машинах, то при создании моделей просмотра используйте фабрики и кеширование определенного типа. Если ваш vm требует дополнительную информацию, просто создайте специальный класс Model, который будет выводиться из Project (или реализует IProject), поэтому вы можете легко использовать принцип сегрегации интерфейса.