Xamarin.forms 容器上的prism null异常。解析()

Xamarin.forms 容器上的prism null异常。解析(),xamarin.forms,eventaggregator,Xamarin.forms,Eventaggregator,行Resources.AddeventAggregator、Container.Resolve;引发空异常 更新 我添加了所有类来解释更多内容。正如@Axemasta所说,没有必要注册IEventAggregator,我删除了注册。现在我不知道如何将Listview EventAggregator行为连接到EventAggregator 这是整个App.xaml代码文件 public partial class App : PrismApplication { /* * Th

行Resources.AddeventAggregator、Container.Resolve;引发空异常

更新 我添加了所有类来解释更多内容。正如@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>

只需验证您是否正在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)
        {

        }
    }

当应用程序初始化时,您不需要注册IEventAggregator,就像INavigationService或IPageDialog一样,您可以直接使用它

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

创建一个事件

您首先需要使用Prism创建一个事件,该事件可以传递给EventAggregator。您的事件应该继承自PubSubEvent,您可以将其作为可选对象传递。因此,您的活动将如下所示:

using System;
using Prism.Events;

namespace Company.App.Namespace.Events
{
    public class SampleEvent : PubSubEvent
    {
    }
}
看看最近的一个应用程序,我最常用的方法是在自定义弹出视图(如参数字典)之间传递数据

订阅活动

当IEventAggregator触发时,任何已订阅该事件的内容都将执行指定的任何代码。在想要接收事件的课堂上,您必须执行以下操作:

将类IEventAggregator传递给构造函数prism,然后执行DI 初始化本地IEventagegrator以用于此类 向处理程序方法订阅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,您只需要在订阅的方法中处理它


希望这足以让你使用IEventAggregator

我对这方面的指导随着Prism的功能增加而不断发展,使这类事情变得更加容易

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

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

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

要使用事件聚合器,不需要注册它。您需要从PubSubEvent继承一个事件,然后只需将其传递到viewmodels/views和subscribe/publish事件中即可!谢谢,有什么简单的例子吗?我将提供一个完整的用例作为这个问题的答案。我已经更新了这个问题。问题是如何从xaml ListView连接到事件?!您好@Behzad您可以在listview中应用x:Name,然后在codebehind中订阅一个方法,通过直接引用listview滚动到您需要的位置。这种方式不是MVVM方式,不是吗?因为我们正在使用codeBehinde@Behzad使用codebehind并不一定会破坏MVVM。在所有概念都相同的情况下,您可以用纯代码编写MVVM应用程序。如果您的viewmodel正在执行与视图相关的操作,那么您正在破坏MVVM。整个问题是视图知道视图模型,但视图模型不知道视图。有时,您需要使用codebehind来完成xamarin表单不允许您正常执行的操作!谢谢你确定这行是正确的吗?在xmlns clr命名空间中找不到类型ioc:ContainerProvider:Prism.ioc;assembly=Prism.forms您使用的是哪个版本?您使用的是什么容器并不重要,因为我们在Prism 7中抽象了DI容器Prism是7,我不能使用Prism。Ioc yetIf如果您仍然使用Prism 6,您就不能使用此功能,因为直到v7才引入此功能
public class ScrollToBehavior : BehaviorBase<ListView>
{
    private IEventAggregator _eventAggregator { get; }

    public ScrollToBehavior(IEventAggregator eventAggregator)
    {
        _eventAggregator = eventAggregator;
    }
}
<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>