WPF MVVM как обновить viewmodel из другой viewmodel [duplicate]

Другим решением было бы поставить вызов: SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this) в конструктор MileageFeeCalculator следующим образом:

@Service
public class MileageFeeCalculator {

    @Autowired
    private MileageRateService rateService; // <--- will be autowired when constructor is called

    public MileageFeeCalculator() {
        SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this)
    }

    public float mileageCharge(final int miles) {
        return (miles * rateService.ratePerMile()); 
    }
}
7
задан codeBlue 20 April 2011 в 16:20
поделиться

5 ответов

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

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

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

10
ответ дан Josh G 22 August 2018 в 20:44
поделиться
  • 1
    Любой из этих методов может быть уместным. Это зависит от контекста. Сцепление не подходит, если виртуальные машины не тесно и концептуально связаны. – Josh G 20 April 2011 в 16:30
  • 2
    Очень полезный ответ, мой класс MainViewModel начинал выглядеть как абсолютный беспорядок. спасибо – Steel Nation 12 April 2013 в 14:43

Стандартный способ связи между 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);
7
ответ дан Adam Rackis 22 August 2018 в 20:44
поделиться
  • 1
    -1. Он говорит о взаимоотношениях между родителями и детьми. Сообщения здесь не очень хорошие. – Euphoric 20 April 2011 в 16:31
  • 2
    Я думаю, что обмен сообщениями должен быть прекрасным. Без обмена сообщениями вам придется каким-то образом связать свои модели просмотров. – Adam Rackis 20 April 2011 в 16:33
  • 3
    Сообщения могут быть или не быть подходящими. Это может быть слишком сложно для этой проблемы, но это хорошее решение. – Josh G 20 April 2011 в 16:34
  • 4
    @Josh G - Я согласен. Существуют и другие способы, которые могли бы работать одинаково хорошо, исходя из его положения. +1 за ваш ответ за показ других – Adam Rackis 20 April 2011 в 16:36
  • 5
    Он попросил «лучшего». решение, но "лучший" очень субъективен и требует больше информации о его контексте. – Josh G 20 April 2011 в 16:39

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

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

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

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

1
ответ дан Euphoric 22 August 2018 в 20:44
поделиться
  • 1
    Я не думаю, что использование посланника в этом случае обязательно плохой дизайн. Это будет зависеть от любого количества факторов, но отправка простого сообщения может быть намного проще и эффективнее, чем настройка отношения OO между двумя виртуальными машинами – Adam Rackis 20 April 2011 в 16:50
  • 2
    Я думаю, что проблема заключается в том, что не существует наилучшего способа сделать это как часть шаблона MVVM. – Will 20 April 2011 в 16:51

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

-1
ответ дан pchajer 22 August 2018 в 20:44
поделиться

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

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

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

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

1
ответ дан zapico 22 August 2018 в 20:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: