【问题标题】:EventAggregator in Prism between ViewModelsPrism 中 ViewModel 之间的 EventAggregator
【发布时间】:2018-01-23 09:45:56
【问题描述】:

我正在尝试使用 eventAggregator 和最新的 Prism v7 制作示例。 该示例是使用 Prism 模板包构建的,一个带有加载另一个页面的按钮的页面,在按钮中我发布一个事件,在第二个页面的构造函数中订阅它,然后在收到事件时写在标签上.

首页:

<StackLayout HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand">
        <Label Text="Welcome to Xamarin Forms and Prism!" />
        <Button Command="{Binding Button1Command}" Text="ContentPage1" />
</StackLayout>

第二页:

<StackLayout HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand">
        <Label
            HorizontalOptions="CenterAndExpand"
            Text="{Binding Message}"
            VerticalOptions="CenterAndExpand" />
    </StackLayout>

第一个视图模型:

public class MainPageViewModel : ViewModelBase
    {    
        IEventAggregator _ea;

        public MainPageViewModel(INavigationService navigationService, IEventAggregator eventAggregator) 
            : base (navigationService)
        {
            Title = "Main Page";    
            _ea = eventAggregator;
        }

        public DelegateCommand<string> Button1Command => new DelegateCommand<string>(Button1Navigate);

        private async void Button1Navigate(string par)
        {           
            _ea.GetEvent<BasicEvent>().Publish("basicEvent");
            await NavigationService.NavigateAsync("PrismContentPage1");    
        }        
    }

第二个视图模型:

public class PrismContentPage1ViewModel : BindableBase
    {
        IEventAggregator _ea;

        private string _message;
        public string Message
        {
            get { return _message; }
            set { SetProperty(ref _message, value); }
        }

        public PrismContentPage1ViewModel(IEventAggregator eventAggregator)
        {
            _ea = eventAggregator;    
            _ea.GetEvent<BasicEvent>().Subscribe(OnInitializationEventFired);
        }

        public void OnInitializationEventFired(string message)
        {
            Message = "received";
        }
    }

标签永远不会得到“received”字符串。 我剥离了许多其他测试的代码:我在第二页中添加了一个按钮以从同一个 ViewModel 中发布,然后就可以工作了。 我调试并检查了 eventAggregator,如果在第二页初始化时它实际上有 1 个项目,即 BasicEvent。

我第一次运行它时,它没有触发事件,然后我回到第一页(我知道,没有取消订阅),再次按下按钮,第二次它被触发,但是,标签中的消息未更改。

看起来一切都很简单,示例(HamburgerMenu,UsingEventAggregator)可以工作,但不是我正在做的这个非常基本的示例,你能帮忙吗? 谢谢

【问题讨论】:

    标签: mvvm xamarin.forms prism


    【解决方案1】:

    您将收到在您订阅事件之后发布的事件。之前触发的所有事件都会丢失,因为您无法追溯订阅。

    【讨论】:

    • 哦,我明白了!我认为 eventAggregator 的工作方式也是,当事件发布时,它会一直存在于 eventAggregator 堆栈中,直到实例化订阅者,然后传递事件。没有这样的吗?
    • 据我所知,prism 中没有内置任何东西,但如果你写的话,你可以用StoringEventAggregator 替换标准的“EventAggregator”。
    【解决方案2】:

    我看到 2 个问题:

    1. “PrismContentPage1ViewModel”在您导航到那里之前不会创建。尝试在“_ea.GetEvent”上添加断点
    2. 您想将一些值传递给下一个视图模型吗?如果是,那么你做错了。使用NavigationParameters

    奖励:不要使用硬编码的视图字符串,如“PrismContentPage1”。如果你可以写nameof。如果您更改视图名称并且导航不再起作用,这将有所帮助,因为您忘记在导航中更改视图名称

    【讨论】:

    • 1.我正在关注 Prism 示例,但我看不到 ViewModel 的任何显式创建,我猜 NavigationService 会处理这个问题。另外,我调试了它,它总是从 _ea.GetEvent.Subscribe 2 传递。是的,我知道这只是让 eventAggregator 工作的示例
    • 你是对的,NavigationService 会处理这个问题。您基本上在某处注册视图和相关的视图模型。通过反射导航到视图会创建视图模型并注入构造函数中的所有服务。或者至少它是我在使用 Prism 框架工作半年后理解底层内容的方式。现在打开 UsingEventAggregator 示例,在您的示例中没有任何东西可以发送发布事件,然后导航到该视图。如果你交换这两条线就可以了吗?
    • 如果我按下第一页中的按钮,则会发布一个事件,然后我导航到订阅同一事件的第二页,但它不会触发。如果我发布和订阅相同的视图模型(作为测试),它会触发。在 UsingEventAggregator 中,它或多或少地执行此操作,发布事件并导航到它订阅的另一个页面并在那里工作。
    • 因为它在发送前订阅。只需添加断点并检查首先是什么:订阅或发布事件。我昨天无法启动他们的示例
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多