Container.Resolve <ieventaggregator>()上的棱镜null异常

时间:2018-07-29 06:24:46

标签: xamarin.forms eventaggregator

Resources.Add(“ eventAggregator”,Container.Resolve())行;引发Null异常。

更新 我添加了所有类以解释更多信息。正如@Axemasta所说,不需要注册IEventAggregator,因此我删除了注册。现在,我不如何将Listview EventAggregator行为连接到EventAggregator。

这是整个App.xaml代码文件。

public partial class App : PrismApplication
{
    /* 
     * The Xamarin Forms XAML Previewer in Visual Studio uses System.Activator.CreateInstance.
     * This imposes a limitation in which the App class must have a default constructor. 
     * App(IPlatformInitializer initializer = null) cannot be handled by the Activator.
     */
    public App() : this(null) { }


    public App(IPlatformInitializer initializer) : base(initializer) { }

    protected override async void OnInitialized()
    {
        InitializeComponent();

        Resources.Add("eventAggregator", Container.Resolve<IEventAggregator>());// Removed on update

        FlowListView.Init();

        await NavigationService.NavigateAsync("NavigationPage/MainPage");

    }

    protected override void RegisterTypes(IContainerRegistry containerRegistry)
    {            
        containerRegistry.RegisterForNavigation<NavigationPage>();
        containerRegistry.RegisterForNavigation<MainPage>();           
    }
}

}

行为类:

public class ScrollToMyModelBehavior : BehaviorBase<ListView>
{
    private IEventAggregator _eventAggregator;
    public IEventAggregator EventAggregator
    {
        get => _eventAggregator;
        set
        {
            if (!EqualityComparer<IEventAggregator>.Default.Equals(_eventAggregator, value))
            {
                _eventAggregator = value;
                _eventAggregator.GetEvent<ScrollToMyModelEvent>().Subscribe(OnScrollToEventPublished);
            }
        }
    }

    private void OnScrollToEventPublished(ListItem model)
    {
        AssociatedObject.ScrollTo(model, ScrollToPosition.Start, true);
    }

    protected override void OnDetachingFrom(ListView bindable)
    {
        base.OnDetachingFrom(bindable);
        // The Event Aggregator uses weak references so forgetting to do this
        // shouldn't create a problem, but it is a better practice.
        EventAggregator.GetEvent<ScrollToMyModelEvent>().Unsubscribe(OnScrollToEventPublished);
    }
}

事件类:

public class ScrollToMyModelEvent : PubSubEvent<ListItem>
{
}

页面浏览模型:

        public MainPageViewModel(INavigationService navigationService, IEventAggregator eventAggregator) 
        : base (navigationService)
    {
        Title = "صفحه اصلی";
        ListHeight = 100;
        ListWidth = 250;

        _eventAggregator = eventAggregator;

        Items items = new Items();
        ListViewItemSouce = items.GetItems();

        MyModels = items.GetItems();
        SelectedModel = ListViewItemSouce[3];
        _eventAggregator.GetEvent<ScrollToMyModelEvent>().Publish(SelectedModel);
    }

页面浏览量:

<StackLayout HorizontalOptions="Center" VerticalOptions="Center" WidthRequest="{Binding ListWidth}" HeightRequest="{Binding ListHeight}"
                         Grid.Row="1" Grid.Column="1">
                <local:NativeListView x:Name="lst3" ItemsSource="{Binding ListViewItemSouce}" Margin="1" BackgroundColor="Transparent" RowHeight="47" HasUnevenRows="false">
                    <ListView.Behaviors>
                        <local:ScrollToMyModelBehavior EventAggregator="{StaticResource eventAggregator}" /> // Error raised that there is not such a static property
                    </ListView.Behaviors>
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <TextCell Text="{Binding Word}"  TextColor="Black"/>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </local:NativeListView>
            </StackLayout>

3 个答案:

答案 0 :(得分:1)

应用初始化时,您无需注册IEventAggregator,就像INavigationServiceIPageDialog一样,您可以直接使用它!

要使用EventAggregator,您应该执行以下操作:

创建活动

您首先需要创建一个事件(使用棱镜),然后可以将其传递给EventAggregator。您的事件应继承自PubSubEvent,您可以向其传递一个对象(可选)。因此您的活动将如下所示:

using System;
using Prism.Events;

namespace Company.App.Namespace.Events
{
    public class SampleEvent : PubSubEvent
    {
    }
}

查看最近使用的应用程序,我最常在自定义弹出视图之间传递数据(例如参数字典)时使用它。

订阅活动

IEventAggregator触发时,订阅该事件的任何人都将执行指定的任何代码。在您要接收该事件的班级中,您必须执行以下操作:

  • 将类IEventAggregator通过构造函数传递(棱镜最终将由DI完成)
  • 初始化本地IEventAggregator以便在此类中使用
  • IEventAggregator订阅处理程序方法。

代码如下所示:

public class TheClassListeningForAnEvent
{
    private readonly IEventAggregator _eventAggregator;

    public TheClassListeningForAnEvent(IEventAggregator eventAggregator)
    {
        _eventAggregator = eventAggregator;
        _eventAggregator.GetEvent<SampleEvent>().Subscribe(OnEventRecieved);
    }

    void OnEventRecieved()
    {
        //Do something here
    }
}

触发事件

现在您已经注册了该活动,您可以触发该活动。将IEventAggregator传递到您要触发事件的任何类中,然后使用Publish Method

public class TheClassPublishingAnEvent
{
    private readonly IEventAggregator _eventAggregator;

    public TheClassListeningForAnEvent(IEventAggregator eventAggregator)
    {
        _eventAggregator = eventAggregator;

        _eventAggregator.GetEvent<SampleEvent>().Publish();
    }
}

这就是它的长短。您可以将任何内容传递给IEventAggregator,只需要使用您所订购的方法即可处理。

希望这足以让您使用IEventAggregator

答案 1 :(得分:0)

只需验证是否在IOS,Android和UWP项目中添加以下代码即可。

IOS- Appdelegate

public class AppdelegateInitializer : IPlatformInitializer
    {
        public void RegisterTypes(IUnityContainer container)
        {

        }
    }

Android-MainActivity

public class MainActivityInitializer : IPlatformInitializer
    {
        public void RegisterTypes(IUnityContainer container)
        {

        }
    }

UWP-- MainPage.cs

public class UwpInitializer : IPlatformInitializer
    {
        public void RegisterTypes(IUnityContainer container)
        {

        }
    }

答案 2 :(得分:0)

随着Prism功能的添加,使这种事情变得更加容易,我对此的指导也在不断发展。

过去,您将IEventAggregator解析并添加为StaticResource的原因是无法注入它。现在,我们有了ContainerProvider,它可以惊人地允许您在XAML中添加需要依赖注入的类型。首先,您可以通过添加IEventAggregator作为构造函数参数,并删除Bindable属性(如果选择)来重构ScrollToBehavior以使用DI模式。

public class ScrollToBehavior : BehaviorBase<ListView>
{
    private IEventAggregator _eventAggregator { get; }

    public ScrollToBehavior(IEventAggregator eventAggregator)
    {
        _eventAggregator = eventAggregator;
    }
}

正如我提到的,您可以在XAML中使用ContainerProvider来解析和提供需要DI的类型,如下所示:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:ioc="clr-namespace:Prism.Ioc;assembly=Prism.Forms"
             xmlns:behavior="using:AwesomeProject.Behaviors
             x:Class="AwesomeProject.Views.ViewA">
  <ListView>
    <ListView.Behaviors>
      <ioc:ContainerProvider x:TypeArguments="behavior:ScrollToBehavior" />
    </ListView.Behaviors>
  </ListView>
</ContentPage>