Обновление модели представления из другой модели представления - PullRequest
7 голосов
/ 20 апреля 2011

У меня есть две модели ViewModel, одна из которых прикреплена к главному окну, а другая - к дочернему окну, которое открывается нажатием кнопки в главном окне.Дочернее окно содержит список элементов, и я хочу выбрать элемент и отобразить его в главном окне, обновив модель представления основного окна.Каков наилучший способ сделать это.Спасибо!

Ответы [ 5 ]

10 голосов
/ 20 апреля 2011

Есть несколько способов сделать это.

  • Передайте ссылку на модель основного / родительского представления в дочерний элемент и попросите ребенка вызвать модель основного вида.

  • Пусть модель дочернего представления инициирует событие, на которое подписывается родитель.

  • Используйте мессенджер / посредник для общения между ними. Родитель подписывается, ребенок отправляет сообщение. Это обеспечивает слабую связь.

  • Установить модель основного вида в качестве глобальной службы. Зарегистрируйте это как-нибудь. Попросите ребенка найти службу (требовать глобальных служб - довольно распространенная проблема), а затем вызвать что-то в глобальном / общем интерфейсе.

По моему опыту, самый простой способ - это # ​​2. Определите событие в модели дочернего представления. Родитель должен будет найти ребенка (я не знаю, содержит ли он его или как построены ваши модели представления) и подписаться на событие.

7 голосов
/ 20 апреля 2011

Стандартный способ связи между ViewModels - это использовать какой-либо тип обмена сообщениями.Хорошей реализацией этого является MVVM Light Toolkit

Вот некоторый (случайный) код с использованием мессенджера по умолчанию:

//Registering:
Messenger.Default.Register<IEnumerable<BookViewModel>>(this, true, fillSourceWith);
Messenger.Default.Register<DisplayModeEnum>(this, ChangeMainTemplates);
//with a specific "token"
Messenger.Default.Register<object>(this, MessageTokens.ClearList, o => BookSource.Clear()); 

//Sending
Messenger.Default.Send<List<BookViewModel>>(newBooks);
Messenger.Default.Send<DisplayModeEnum>(DisplayModeEnum.MediumLayout);
Messenger.Default.Send<object>(null, MessageTokens.ClearList);
1 голос
/ 20 апреля 2011

У меня была такая же проблема несколько дней назад; -)

Наконец, я использовал посредник для связи обеих моделей представления. На самом деле я использовал Messenger от MVVM Light.

public void Search(object parameter)
        {
            ChildWindow window = new ChildWindow();

            SearchWindow pageSearch = new SearchWindow();

            window.Content = pageSearch;
            window.Show();

            Messenger.Default.Register<Messages.CloseWindowMessage>(this, action => this.closeWindow(action));
        }

После этого я определил Сообщение всем, что мне нужно было узнать из главного окна:

public class CloseWindowMessage : MessageBase
    {
        public bool Result { get; set; }
        public Model.Selected Selected { get; set; }
    }

Наконец, сообщение обратно из дочернего окна, вам нужно только зарегистрировать сообщение с результатом и объектом, который вы хотите вернуть.

Чтобы закрыть окно, вам необходимо зарегистрироваться из выделенного кода вашего представления.

1 голос
/ 20 апреля 2011

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

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

Обмен сообщениями используется, когда обе модели представления логически не связаны.

[rant] Разве люди даже не знают основных принципов ООП или как? [/ Напыщенная]

0 голосов
/ 25 апреля 2011

Я думаю, что лучший способ передать сообщение между двумя моделями представления - это программирование событий.

...