2009-04-28 2 views
20

В моем WPF приложения Я имею 2 Windows (как Windows, имеют свои собственные ViewModel):WPF MVVM Правильный способ стрелять событие на вид из ViewModel

  1. Главное окно приложения, которое отображает список с кучей слов (оценка в MainViewModel)

  2. диалогового окна, которое позволяет пользователям добавлять новые элементы в список (связанный с AddWordViewModel)

MainViewModel имеет Статьи свойство Li st (эта коллекция заполнена одним из классов обслуживания), связанная с ListBox главного окна

AddWordViewModel имеет SaveWordCommand, который связан с кнопкой «Сохранить диалог диалога Word». Задача состоит в том, чтобы взять текст, введенный пользователем, и передать его классу обслуживания.

После того, как пользователь нажмет на кнопку «Сохранить», мне необходимо уведомить MainViewModel, чтобы перезагрузить статьи из службы.

Моя идея состояла в том, чтобы выставить общественную команду в MainViewModel и выполнить его AddWordViewModel

Что является правильным способом это осуществить?

Спасибо!

ответ

18

Event Aggregators - отличный способ решить эту проблему. В принципе, есть централизованный класс (для упрощения, скажем, это Синглтон и встретить возможный гнев антиин-одиночных парней), который отвечает за передачу событий от одного объекта к другому. С вашими именами классов использование может выглядеть следующим образом:

public class MainViewModel 
{ 
    public MainViewModel() 
    { 
     WordAddedEvent event = EventAggregator.Instance.GetEvent<WordAddedEvent>(); 
     event.Subscribe(WordAdded); 
    } 

    protected virtual void WordAdded(object sender WordAddedEventArgs e) 
    { 
     // handle event 
    } 
} 

public class AddWordViewModel 
{  
    //From the command 
    public void ExecuteAddWord(string word) 
    { 
     WordAddedEvent event = EventAggregator.Instance.GetEvent<WordAddedEvent>(); 
     event.Publish(this, new WordAddedEventArgs(word)); 
    } 
} 

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


Если вы хотите, чтобы избежать синглтона (и для целей тестирования я хотел бы предложить вам сделать), то это может быть стоит посмотреть в зависимости инъекции, хотя это на самом деле это совершенно другой вопрос.


ОК, окончательная мысль. Я вижу, перечитывая ваш вопрос, что у вас уже есть какой-то класс Word Service, который обрабатывает поиск и хранение объектов Word. Нет причин, по которым служба не может нести ответственность за повышение события при добавлении нового слова, поскольку оба ViewModels уже связаны с ним. Хотя я по-прежнему предполагаю, что EventAggregator является более гибким и лучшим решением, но YAGNI может применяться здесь

public class WordService 
{ 
    public event EventHandler<WordAddedEventArgs> WordAdded; 

    public List<string> GetAllWords() 
    { 
     //return words 
    } 

    public void SaveWord(string word) 
    { 
     //Save word 
     if (WordAdded != null) WordAdded(this, new WordAddedEventArgs(word)); 
     //Note that this way you lose the reference to where the word really came from 
     //probably doesn't matter, but might 
    } 
} 

public class MainViewModel 
{ 
    public MainViewModel() 
    { 
     //Add eventhandler to the services WordAdded event 
    } 
} 

То, что вы хотите делать, чтобы избежать хотя вводят связь между ViewModels, что вы будете создавать с помощью вызова команды на одном ViewModel с другим, это сильно ограничит ваши возможности для расширения приложения (что, если второй ViewModel заинтересовался новыми словами, теперь ли ответственность AddWordViewModel также сказать об этом?)

+0

Благодарим вас за очень подробный ответ. Нужно будет копаться в нем :) Много веселья наступает :) –

+0

Я поступил с полным OO с массивным графом объектов для моей реализации MVVM.2 года вниз по линии и сделать структурные изменения довольно сложно. Мне жаль, что я не пошел на шаблон агрегатора/посредника, поскольку гибкость огромна. ОСТОРОЖНО: утечка памяти. Убедитесь, что ваш агрегатор использует слабые ссылки. – Gusdor

Смежные вопросы