Рекомендуется ли иметь ссылку на RegionManager призмы в модели просмотра?

Я разрабатываю составное приложение WPF с использованием PRISM. У меня есть окно с родительским UserControl. Для этого родительского элемента управления пользователем определено множество дочерних регионов. дочерние представления экспортируют себя с помощью атрибута "REGIONEXPORT" MEF. Каждое дочернее представление импортирует / создает свою собственную модель представления. В родительском элементе управления пользователя есть кнопки «ОК» и «Отмена». Нажав «ОК», я хочу подтвердить и сохранить все дочерние модели. Если какая-либо проверка не удалась, то об этом должна знать модель просмотра родительского элемента управления. Для этого я использую составную команду и устанавливаю ее в RegionContext. Каждая дочерняя модель просмотра получает эту составную команду через контекст региона, и надеюсь, вы понимаете, что в основном мне нужно обмениваться данными между родительскими и дочерними моделями просмотра. Поэтому мне нужно получить RegionContext в дочерней модели просмотра, для которой я импортирую RegionManager в конструкторе модели просмотра (с использованием конструктора импорта) из RegionManager, я получаю контекст региона, а затем команды.

public class FooViewModel
{
     [ImportingConstructor]
     public FooViewModel(IRegionManager regionManager)
     {
        var regionContext = regionManager.RegionContext;
     }
}
  1. Хорошая ли практика иметь регионального менеджера в представлении модели ??
  2. Это не нарушает MVVM? у нас есть просмотр связанных вещей в моделях просмотра
  3. Есть ли лучший подход для обмена данными между моделями просмотра (кроме агрегаторов событий)

person Sivasubramanian    schedule 23.02.2017    source источник


Ответы (1)


Получение ссылки на диспетчер регионов через конструктор модели представления не является чем-то необычным. Это предпочтительный метод для его получения. Я делаю это все время, когда мне нужно использовать Региональный менеджер для навигации.

Такой подход не нарушает работу MVVM. Хотя я не уверен, что вы планируете делать с самим RegionContext.

Другой способ передачи данных от одной виртуальной машины к другой - через NavigationParameters и функцию менеджеров регионов RequestNavigate. Пример ниже.

private readonly IRegionManager _regionManager;

public YourViewModel(IRegionManager regionManager)
{
    _regionManager = regionManager;
}

Private void DoNavigation()
{
    var parameters = new NavigationParameters();
    parameters.Add("Key", <a value or an object to pass>);
    _regionManager.RequestNavigate(“ContentRegion”, “YourViewName”, parameters);
}

Вы можете проверить набор параметров на наличие значений в OnNavigatedTo методе принимающей виртуальной машины.

public override void OnNavigatedTo(NavigationContext navigationContext)
{
    var paramKey = navigationContext.Parameters.Where(item => item.Key == "Key").FirstOrDefault();

    if (paramKey.Value != null)
    {
        // Do something…
    }    
}

Вам необходимо реализовать INavigationAware, чтобы OnNavigatedTo заработал.

РЕДАКТИРОВАТЬ:

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

При использовании службы общего доступа некоторые или все модели представления могут иметь ссылку на нее, и при изменении свойства в службе любой объект, имеющий ссылку на нее, может действовать. Эта служба общего доступа может реализовать BindableBase, который поставляется с Prism, и, следовательно, уведомлять, когда происходят изменения. Зарегистрируйте службу общего доступа в любом используемом вами контейнере, поместите ее в ctor модели представления, укажите соответствующие свойства.

Пример общей службы

person R. Richards    schedule 23.02.2017
comment
Спасибо, Ричард. :) Но все же я в замешательстве. Этот RegionManager содержит регионы и представления и доступ к региональному менеджеру (просмотр связанных вещей) в модели представления, я считаю, что это противоречит MVVM. - person Sivasubramanian; 24.02.2017
comment
Никто не заставляет вас ориентироваться в первую очередь на просмотр, хотя ViewModelLocator делает это простым и понятным. Вы также можете перемещаться сначала по модели просмотра, а затем к регионам, содержащим ваши модели просмотра. - person Haukinger; 24.02.2017
comment
Привет @Haukinger, в моем требовании нет навигации. У меня есть родительский вид и дочерний вид, оба вида не имеют прямой ссылки. Родительское представление создает свою виртуальную машину, дочернее представление создает свою виртуальную машину. теперь мне нужно обмениваться данными между родительским и дочерним виртуальными машинами. Для этого я использую RegionContext. - person Sivasubramanian; 26.02.2017
comment
@Sivasubramanian У вас проблемы с агрегатором событий? Почему бы не использовать это, если вам не нравится подход RegionContext? - person R. Richards; 26.02.2017
comment
@Sivasubramanian, в этом случае просто имейте службу, доступную для обеих моделей представления, которая снабжает их обеими данными. - person Haukinger; 26.02.2017
comment
@Sivasubramanian Я обновил ответ, добавив опцию добавления (общая служба) и указатель на пример, который Хаукингер публиковал в прошлом. - person R. Richards; 26.02.2017
comment
@Richards: Меня устраивает агрегатор событий, но члены моей команды не хотят этого подхода из-за того, что в других модулях существует слишком много дополнительных событий паба (забавно, правда :)) Я лично считаю, что агрегаторы событий лучше в этом сценарии. Вместо того, чтобы импортировать региональные менеджеры в конструктор. Также, если где-нибудь мне нужно создать экземпляр FooViewModel, я буду делать эту новую FooViewModel (null); - person Sivasubramanian; 27.02.2017
comment
@Haukinger: Спасибо за вашу поддержку. Наличие услуги - хороший подход, но он не соответствует моим требованиям. Тот подход, который я уже пробовал, сервис должен быть одноэлементным. поправьте меня, если я ошибаюсь. если служба одноэлементная, и что, если мне нужно показать два родительских представления и два дочерних представления (в основном два немодальных окна) одновременно? Общие данные в моем случае - это составная команда. когда оба окна открыты, первое окно начнет реагировать на второе окно, что неприемлемо с точки зрения моих требований. - person Sivasubramanian; 27.02.2017
comment
@ R.Richards: Спасибо за вашу поддержку. Я буду использовать подход RegionManager. - person Sivasubramanian; 27.02.2017