事件不会跨模块触发(prism、MVVM、silverlight c#)

发布于 2024-09-27 15:18:53 字数 1323 浏览 1 评论 0原文

对了哦,现在我相信我设置了这个应用程序是正确的,但如果我错了,请纠正我,为了简单起见,我在我的引导程序中加载了 3 个模块,一个是导航模块,另外两个是视图。

如果我加载模块并在初始化方法中将它们添加到一切正常的区域,则独立地在代码中,但是当然我喜欢更多的控制。

现在,在导航视图模型中,我有一个事件聚合器,它发布一个事件(如果这很重要,则从 EventArgs 继承的类),其他两个模块已订阅此事件,但

/// <summary>
    /// Carries the out menu item selection methods.
    /// </summary>
    /// <param name="e">The <see cref="TMBL.Web.TMBLCore.Controls.Assets.NavigationViewSelectionEventArgs"/> instance containing the event data.</param>
    public void CarryOutMenuItemSelectionMethods(NavigationViewSelectionEventArgs e)
    {
        _eventAggregator.GetEvent<NavigationMenuItemSelectedEvent>().Publish(e);
    }

在导航 ViewModel 中都没有收到它,然后在新闻模块中订阅

_eventAggregator.GetEvent<NavigationMenuItemSelectedEvent>().Subscribe(NavigationMenuReturnedEvent,
                                                                               ThreadOption.UIThread);

看起来很简单,我可以在我的导航模块中订阅此事件,它会拾取它,它只是不会超出模块之外,需要做什么才能实现这一目标?

此外,事件聚合器通过依赖项注入推入模块构造函数,然后存储在那里并通过构造函数传递到视图和视图模型(顺便说一句,视图优先方法)。虽然我在这里我不知道这是否是问题的原因,但是让模块存储事件聚合器的实例并以这种方式传递它是否不好,例如

_displayNewsView = new DisplayNewsView(new DisplayNewsViewModel(_eventAggregator));

或者事件聚合器应该以不同的方式获取视图模型?

谢谢你的时间

Righty oh now I believe ive set this application up right but correct me if im wrong, for simple sake i have in my bootstrapper 3 modules loaded, one is a navigation module, and two others the views.

Independently in code if i load the modules and in the initialize method add them to a region that all works fine, however ofcourse id like some more control.

Now in the navigation view model i have an event aggregator which publishes an event (class that inherits from EventArgs if thats important) the other two modules have subscribed to this event but neither recieve it,

/// <summary>
    /// Carries the out menu item selection methods.
    /// </summary>
    /// <param name="e">The <see cref="TMBL.Web.TMBLCore.Controls.Assets.NavigationViewSelectionEventArgs"/> instance containing the event data.</param>
    public void CarryOutMenuItemSelectionMethods(NavigationViewSelectionEventArgs e)
    {
        _eventAggregator.GetEvent<NavigationMenuItemSelectedEvent>().Publish(e);
    }

in navigation ViewModel,and then subscribed to in news module

_eventAggregator.GetEvent<NavigationMenuItemSelectedEvent>().Subscribe(NavigationMenuReturnedEvent,
                                                                               ThreadOption.UIThread);

Seemed simple enough, i can subscribe to this event in my navigation module and it picks it up, it just wont go outside the module, what does one need to do to achieve this?

Also the event aggregator is pushed in through dependency injection to the modules constructor, then stored there and passed onthrough constructors to the viewsand view models (views first approach by the way). Whilst im here I dont know if this is the cause of the problem or not but is it bad to have the module store an instance of event aggregator and pass it on this way eg

_displayNewsView = new DisplayNewsView(new DisplayNewsViewModel(_eventAggregator));

Or should the event aggregator get to the viewmodels a different way?

Thanks for you time

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

A君 2024-10-04 15:18:53

您正在正确注入事件聚合器,但您需要检查一些事情。

1) 事件聚合器实例对于应用程序来说是全局的,而不是由每个模块创建的。跨模块必须使用相同的实例。这应该在应用程序引导程序中创建并传递给每个模块。

2) NavigationMenuItemSelectionEvent 是否在跨模块共享的公共程序集中定义?如果是这种情况(正如我所期望的),那么请确保跨模块使用相同的程序集。当您使用调试器加载应用程序并使用“模块”窗口(“调试”>“Windows”菜单)查看加载的程序集时,您可以检查这一点。该程序集应该只列出一次。

如果您看到公共程序集加载了多次,那么可能是因为您正在从不同的目录加载模块并且公共程序集未签名。 .Net 会将它们视为单独的,因此 NavigationMenuItemSelectionEvent 类型将不匹配。

要么对程序集进行签名,确保所有模块都使用程序集的同一实例,要么确保从同一目录加载所有模块(包括应用程序,如果它也使用通用程序集)。

You are injecting the event aggregator correctly but there are a couple of things you need to check.

1) Is the event aggregator instance global to the application and not created by each module. The same instance must be used across modules. This should get created within the application bootstrapper and passed to each module.

2) Is the NavigationMenuItemSelectionEvent defined in a common assembly that is shared across modules? If this the case (as I would expect) then make sure the same assembly is used across modules. You can check this when you load the application using the debugger and view the loaded assemblies using the Modules window (Debug > Windows menu). The assembly should only be listed once.

If you see the common assembly loaded multiple times then it could be down to that you are loading modules from different directories and the common assembly is NOT signed. .Net will treat these as separate and therefore the NavigationMenuItemSelectionEvent type will not match.

Either have the assembly signed ensuring all modules using the same instance of the assembly or ensure that all modules get loaded from the same directory (including the application if it too uses the common assembly).

岁月苍老的讽刺 2024-10-04 15:18:53

好吧,堆栈溢出丢失了我的精彩回复。因此,我的引导程序中需要一个事件聚合器实例,因为所有模块都需要使用相同的服务,这对我来说很有意义。但是我认为依赖注入可以解决这个问题,我需要在引导程序中提供事件聚合器的实例吗?我的问题有两个,首先如何实例化它,

 protected override DependencyObject CreateShell()
    {
        _eventAggregator = new EventAggregator();
        var shell = Container.Resolve<Shell>();
        Application.Current.RootVisual = shell;
        return shell;
    }

这行得通吗?其次,我如何将此实例传递到引导捆绑程序中的模块,因为在添加到模块目录时创建它们时,我相信

 protected override IModuleCatalog GetModuleCatalog()
    {
        var catalog = new ModuleCatalog();
        catalog.AddModule(typeof(TMBLCoreModule), InitializationMode.WhenAvailable);
        catalog.AddModule(typeof(NewsModule), InitializationMode.WhenAvailable);
        catalog.AddModule(typeof(UserModule), InitializationMode.WhenAvailable);
        return catalog;
    }

我将如何将事件聚合器传递到每个模块中。我快速谷歌了一下,但还没有找到这些信息,抱歉我的无知

Okay stack overflow lost my nice big reply. So I need an event aggregator instance in my bootstrapper as all modules need to use the same service, this makes sense to me. However I thought dependency injection would take care of this, I need an instance of the event aggregator in my bootstrapper? my issue with this is two fold firstly how to instaniate it

 protected override DependencyObject CreateShell()
    {
        _eventAggregator = new EventAggregator();
        var shell = Container.Resolve<Shell>();
        Application.Current.RootVisual = shell;
        return shell;
    }

Would that work? Secondly how do I pass this instance to my modules in the boot strapper as at the moment they are created when added to the module catalogue i believe

 protected override IModuleCatalog GetModuleCatalog()
    {
        var catalog = new ModuleCatalog();
        catalog.AddModule(typeof(TMBLCoreModule), InitializationMode.WhenAvailable);
        catalog.AddModule(typeof(NewsModule), InitializationMode.WhenAvailable);
        catalog.AddModule(typeof(UserModule), InitializationMode.WhenAvailable);
        return catalog;
    }

How would I then pass the event aggregator into each module. I've had a quick google but havent been able to find this information yet, sorry for my ignorance

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文