Как загрузить модуль при использовании событий - PullRequest
0 голосов
/ 10 ноября 2018

Я очень новичок в экосистеме C # \ Prism. Я хочу подключить модули через события, но если просто отправить событие:

_eventAggregator.GetEvent<LoginSuccessEvent>().Publish(new LoginSuccessEventArgs(user));

тогда мой обработчик событий не работает. Как я понимаю, это происходит, потому что приемник ViewModel не создается (я проверил с точкой останова в отладчике). Но если я перейду от отправителя события:

_regionManager.RequestNavigate(RegionNames.RootRegion, "WorksheetListView");
_regionManager.RequestNavigate(RegionNames.WorksheetDetailsRegion, "WorksheetDetailsView");
_eventAggregator.GetEvent<LoginSuccessEvent>().Publish(new LoginSuccessEventArgs(user));

Затем перед первым получателем команд RequestNavigate вызывается конструктор ViewModel.

_regionManager = regionManager;
_model = container.Resolve<WorksheetListModel>();
OpenWorksheetCommand = new DelegateCommand(OpenWorksheet);
Worksheets = _model.WorksheetList;
eventAggregator.GetEvent<LoginSuccessEvent>().Subscribe(OnLoginSuccessEvent);

Я попытался добавить регистрацию класса ViewModel в модуль приемника:

_container.RegisterType<WorksheetListViewModel>();

Но не повезло. Я не хочу добавлять эту регистрацию отправителю, потому что создается жесткая связь.

Но я хочу иметь слабую связь между modulel и выполнять навигацию из RECIEVER, но не из SENDER. Так что отправитель не будет ничего знать о получателе. Как я могу достичь этого? Спасибо.

Ответы [ 2 ]

0 голосов
/ 10 ноября 2018

Хорошо. Я нашел кучу вопросов вроде («EventAggregator не работает вокруг модулей»). Мое решение очень простое. Я создаю экземпляр моей модели представления, поэтому вызывается также конструктор с подпиской на события.

using Microsoft.Practices.Unity;
using Prism.Modularity;
using Prism.Regions;
using Prism.Events;
using Prism.Unity;

using WorksheetListModule.ViewModels;
using WorksheetListModule.Views;
using WorksheetListModule.Models;


namespace WorksheetListModule
{
    public class WorksheetListModule : IModule
    {
        IRegionManager _regionManager;
        IUnityContainer _container;
        IEventAggregator _eventAggregator;

        public WorksheetListModule(RegionManager regionManager, IUnityContainer container, IEventAggregator eventAggregator)
        {
            _regionManager = regionManager;
            _container = container;
            _eventAggregator = eventAggregator;
        }

        public void Initialize()
        {
            WorksheetListViewModel vm = new WorksheetListViewModel(_regionManager, _container, _eventAggregator);
            _container.RegisterInstance<WorksheetListViewModel>(vm);
            _container.RegisterType<WorksheetListModel>();
            _container.RegisterTypeForNavigation<WorksheetListView>();
            _container.RegisterTypeForNavigation<WorksheetDetailsView>();
        }
    }
}

Ключевой функцией здесь является функция RegisterInstance. Теперь я могу выполнять навигацию в приемнике событий, а отправитель событий теперь не знает никакой информации о внутренней структуре приемника.

0 голосов
/ 10 ноября 2018

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

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

Пример:

public interface IUserManager : INotifyPropertyChanged // this is optional if you keep the event
{
    // returns null if no user is logged in
    string CurrentUserName { get; }

    // returns true if user name and password are valid and updates CurrentUserName
    bool TryLogin( string userName, string password );
}
...