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

How to correctly send event-messages between modules in Prism framework?

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

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

我的想法是,当用户登录时,我会发布一个名为 UserLoggedIn 的事件,然后在主视图模型上,我会监听该事件。当事件被触发时,我会显示 landing/home 视图。

所以我创建了这样的活动

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 中触发。

我确保视图 HomeViewHomeViewModel 连接正确,方法是在模块初始化时直接加载 HomeView 进行测试。

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

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

所以我可以学习 better/recommended 方法,从 LoginViewModel 显示着陆视图是否比使用 event/listener 更好...为什么?此外,如果直接从 LoginViewModel 显示着陆视图,那么推荐的导航方法是什么?使用 Region.Add() 方法或 RegionManager.RequestNavigate?

is it better to show the landing view from the LoginViewModel instead of using event/listener....

是的。

and why?

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

Also, if showing the landing view directly from the LoginViewModel then what is the recommended method to navigate; using Region.Add() method or RegionManager.RequestNavigate?

如果有的话,第三个 class 应该监听 UserLoggedIn,但这与直接使用 IRegionManager 相比没有任何好处。事实上,它更糟糕,因为你必须人为地创建这个class。旁注:如果您在 Container.Resolve<HomeView>(); 之后和登录之前等待垃圾收集器,您将不会转到登录页面,因为没有订阅者(再次)。