如何在Prism框架中的模块之间正确发送事件消息?

时间:2018-03-03 19:56:54

标签: c# wpf mvvm prism prism-6

我正在尝试使用MVVM设计模式构建一个WPF Prism基础应用程序。

当我的应用首次启动时,我想要求用户登录。登录后,我想显示带有用户名和按钮的默认登录页面。

我的想法是,当用户登录时,我会在家庭视图模型上发布一个名为UserLoggedIn的事件,我会听那个事件。触发事件后,我会显示登陆/主页视图。

所以我创建了这样的事件

public class UserLoggedIn : PubSubEvent<User>
{
}

然后在LoginViewModel我处理登录并发布事件,如此

    private void HandleLogin(LoginView loginView)
    {
        try
        {
            User user = AuthenticationService.Authenticate(Username, loginView.GetPassport());

            IUserPassport passport = PassportManager.Get(user.Username);

            if (passport == null)
            {
                // Create a new session 
                passport = new UserPassport(new CustomIdentity(user), RegionManager);
            }
            // Assign the current session
            PassportManager.SetCurrent(passport);

            // Trigger the event
            EventAggregator.GetEvent<UserLoggedIn>().Publish(passport);

            // Deactivate the login view
            RegionManager.GetMainRegion().Deactivate(loginView);
        }
        catch (Exception ex)
        {
              //Do something with the error
        }
    }

最后在我的HomeViewModel又名我的着陆视图中,我有以下代码来监听UserLoggedIn事件。

public class HomeViewModel : BindableBase
{
    protected IUnityContainer Container { get; set; }
    protected ICoreRegionManager RegionManager { get; set; }
    private IEventAggregator EventAggregator { get; set; }

    public HomeViewModel(IUnityContainer container, ICoreRegionManager regionManager, IEventAggregator eventAggregator)
    {
        Container = container;
        RegionManager = regionManager;
        EventAggregator = eventAggregator;
        eventAggregator.GetEvent<UserLoggedIn>().Subscribe(ShowTheLangingPage);
    }

    private void ShowTheLangingPage(User user)
    {
        var homeView = Container.Resolve<HomeView>();

        RegionManager.AddToMainRegion(homeView);
        FullName = user.FirstName;
    }

    // I am using PropertyChange.Fody package, so this propery will automaticly raise the PropertyChange event.
    public string FullName { get; set; }
}

问题是ShowTheLangingPage方法永远不会按预期在我的HomeViewModel中触发。

我确保通过直接在模块初始化上加载HomeView进行测试来正确连接视图HomeViewModelHomeView

此外,如果在发布活动之前添加Container.Resolve<HomeView>();,我就会调用ShowTheLangingPage。就像我必须手动解析HomeView才能听取此事件。

如何正确收听UserLoggedIn事件,以便显示相应的视图。

所以我可以学习更好/推荐的方式,是否更好地显示LoginViewModel的着陆视图而不是使用事件/监听器....为什么?此外,如果直接从LoginViewModel显示着陆视图,那么推荐的导航方法是什么;使用Region.Add()方法或RegionManager.RequestNavigate

1 个答案:

答案 0 :(得分:0)

  

最好是从LoginViewModel显示着陆视图而不是使用事件/侦听器....

  

为什么?

因为这就是服务(如IRegionManager)的用途,为您的视图模型和其他服务做些事情。此外,您已经注意到,事件只能由活动对象订阅。

  

此外,如果直接从LoginViewModel显示着陆视图,那么推荐的导航方法是什么;使用Region.Add()方法或RegionManager.RequestNavigate?

如果有的话,第三堂课应该听取UserLoggedIn,但直接使用IRegionManager并没有收获。事实上,情况更糟,因为你必须人为地创造这个类。附注:如果您在Container.Resolve<HomeView>();之后等待垃圾收集器,并且在登录之前,您将不会进入登录页面,因为没有订户(再次)。