Caliburn.micro parent-> child и child-> родительские взаимодействия - PullRequest
0 голосов
/ 20 января 2019

Я работаю над приложением WPF, используя Caliburn.micro. Там у меня есть mainViewModel, которая расширяет Conductor, и две subviewModel, которые расширяют Screen. Эти две модели вида активируются с помощью элемента управления вкладками в моей MainViewModel. У меня есть строки, которые принадлежат MainViewModel, и мне нужно провести эти строки для обеих subViewModel. Строки, которые мне нужно передать в subViewModels, связаны в MainView с текстовыми полями. Я хотел бы передать эти строки в subViewModel, и даже если эти строки изменены из MainViewModel, мне нужно обновить мои subViewModel. На данный момент я даю MainViewModel в качестве параметра в конструкторе каждого subViewModel, но я уверен, что есть лучший способ в основном я хотел бы привязать дочернее свойство к родительскому свойству и сообщить о любом из них, если свойство было изменено в родительском или дочернем ViewModel. Можете ли вы указать мне правильное направление?

1 Ответ

0 голосов
/ 20 января 2019

Вы можете использовать EventAggregators для достижения этой цели.

Для незнакомых людей Event Aggregator - это сервис, который предоставляет возможность публикации объекта от одного объекта к другому в свободно основанная мода.

Подробнее об агрегаторах событий можно прочитать здесь

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

public class CustomMessage
{
    public string String1 { get; set; }
}

Теперь вы переходите к ParentViewModel и создаете экземпляр агрегатора событий.

private IEventAggregator _eventAggregator;
[ImportingConstructor]
public ShellViewModel(IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator;
_eventAggregator.Subscribe(this);
}

В установщике вашего свойства, которое связано с вашим текстовым полем, вы теперь добавили бы код для публикации сообщения с помощью Event Aggregator.

Например,

public string String1
{
    get => _string1;
    set
    {
        if (_string1.Equals(value)) return;

        _string1 = value;
        _eventAggregator.PublishOnUIThread(new CustomMessage
        {
            String1 = _string1,
        });

    }

}

Теперь вы переходите к своей модели просмотра ребенка и подписываетесь на агрегатор событий.

private IEventAggregator _eventAggregator;
[ImportingConstructor]
public SecondWinViewModel(IEventAggregator eventAggregator)
{
    _eventAggregator = eventAggregator;
    _eventAggregator.Subscribe(this);
}

Чтобы подписаться на конкретное сообщение (в данном случае CustomMessage), вам необходимо реализовать интерфейс IHandle.

[Export(typeof(SecondWinViewModel))]
public class SecondWinViewModel : Screen, IHandle<CustomMessage>

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

public void Handle(CustomMessage message)
{
    String1 = message.String1;
    NotifyOfPropertyChange(nameof(String1));
}

Вы можете сделать то же самое для нескольких параметров, добавив дополнительные свойства в ваше CustomMessage. Таким же образом вы можете передавать сообщения из Child Vm в Parent Vm.

...