Xamarin.forms 容器上的prism null异常。解析()
行Resources.AddeventAggregator、Container.Resolve;引发空异常 更新 我添加了所有类来解释更多内容。正如@Axemasta所说,没有必要注册IEventAggregator,我删除了注册。现在我不知道如何将Listview EventAggregator行为连接到EventAggregator 这是整个App.xaml代码文件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
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>