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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在Prism框架中的模块之间正确发送事件消息?相关的知识,希望对你有一定的参考价值。

我正在尝试使用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进行测试来正确连接View HomeViewModelHomeView

另外,如果在我发布事件之前添加Container.Resolve<HomeView>();,我打电话给ShowTheLangingPage。它就像我必须手动解决HomeView它听它的事件。

我怎样才能正确地听UserLoggedIn事件,以便我可以显示相应的视图。

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

答案

是否更好地从LoginViewModel显示着陆视图而不是使用事件/监听器....

是。

为什么?

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

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

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

以上是关于如何在Prism框架中的模块之间正确发送事件消息?的主要内容,如果未能解决你的问题,请参考以下文章

C# WPF MVVM模式Prism框架下事件发布与订阅

Prism框架研究

无法使用 Prism 从回调方法内部导航

2021-10-11 WPF上位机 62-Prism框架对象DelegateCommand

如何在 Xamarin 表单中的视图模型之间最好地传递信息 - Prism [关闭]

WPF Prism框架下基于MVVM模式的命令绑定事件