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>
答案 0 :(得分:1)
应用初始化时,您无需注册IEventAggregator
,就像INavigationService
或IPageDialog
一样,您可以直接使用它!
要使用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>