Обновление viewmodel из другой viewmodel

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

5 ответов


существует множество способов сделать это.

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

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

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

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

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


стандартным способом связи между 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);

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

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

Messaging используется, когда обе ViewModels логически не связаны.

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


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

наконец, я использовал посредника для связи обеих моделей представления. На самом деле я использовал мессенджер от 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; }
    }

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

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


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