silverlight - 使用 Prism 进行事件订阅,给出方法访问异常

标签 silverlight prism

我在 View 模型中订阅了一个事件。事件订阅是在通过 Unity 创建的 View 模型的构造函数中完成的。

我发现如果我订阅为:

showViewAEvent.Subscribe(ShowViewAHasBeenRequested) 或 showViewAEvent.Subscribe(ShowViewAHasBeenRequested, False) 我收到以下错误:

       // {System.MethodAccessException: ModuleA.Views.ModuleAViewModel.ShowViewAHasBeenRequested(Boolean)
       //at System.Delegate.BindToMethodInfo(Object target, RuntimeMethodHandle method, RuntimeTypeHandle methodType, DelegateBindingFlags flags)
       //at System.Delegate.CreateDelegate(Type type, Object firstArgument, MethodInfo method, Boolean throwOnBindFailure)
       //at System.Delegate.CreateDelegate(Type type, Object firstArgument, MethodInfo method)
       //at Microsoft.Practices.Composite.Events.DelegateReference.TryGetDelegate()
       //at Microsoft.Practices.Composite.Events.DelegateReference.get_Target()
       //at Microsoft.Practices.Composite.Events.EventSubscription`1..ctor(IDelegateReference actionReference, IDelegateReference filterReference)
       //at Microsoft.Practices.Composite.Presentation.Events.CompositePresentationEvent`1.Subscribe(Action`1 action, ThreadOption threadOption, Boolean keepSubscriberReferenceAlive, Predicate`1 filter)
       //at Microsoft.Practices.Composite.Presentation.Events.CompositePresentationEvent`1.Subscribe(Action`1 action, ThreadOption threadOption, Boolean keepSubscriberReferenceAlive)
       //at Microsoft.Practices.Composite.Presentation.Events.CompositePresentationEvent`1.Subscribe(Action`1 action, Boolean keepSubscriberReferenceAlive)
       //at ModuleA.Views.ModuleAViewModel..ctor(IEventAggregator eventAggregator, IRegionManager regionManager)
       //at BuildUp_ModuleA.Views.ModuleAViewModel(IBuilderContext )
       //at Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlan.BuildUp(IBuilderContext context)
       //at Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context)
       //at Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)}

但是,如果我在事件订阅上将标志设置为 true,则不会收到错误。

由于我是 prism 的新手,我仍在尝试确定是否在正确的位置创建订阅。

京东。

最佳答案

这是一个已知问题,此处有完整记录:

http://compositewpf.codeplex.com/WorkItem/View.aspx?WorkItemId=4925

CompositePresentationEvent<>.Subscribe() 中的错误可防止弱事件引用标题为必填项

描述 描述为必填项 概述:

此类的 Subscribe() 方法被记录为默认创建 WeakReferences,或者在包含该参数的重载中指定为 keepSubscriberReferenceAlive=false 时。

详细信息:

只有在提供过滤器委托(delegate)时才能正确观察到此行为。在所有其他情况下(以及 Subscribe() 方法的所有重载),都会创建强引用 - 无论记录的默认值如何,也无论为 keepSubscriberReferenceAlive 参数提供的任何值如何。

此错误的根源可以在该方法的以下重载中找到:

CompositePresentationEvent.Subscribe(操作操作,ThreadOption threadOption,bool keepSubscriberReferenceAlive,谓词过滤器)

在此方法中,检查“filter”参数。如果过滤器不为空,则处理会正确继续。但是,如果此参数为 null,则创建一个新的传递委托(delegate)(始终返回 true)并将其用于过滤器。该错误在于,从此传递委托(delegate)创建的 DelegateReference 对象将 keepReferenceAlive 参数硬编码为值“true”。该值不应被硬编码,而应传递传入参数 keepSubscriberReferenceAlive。

解决方法:

此问题有一个简单的解决方法。注册订阅时,您应该始终使用上述详细重载,并始终提供过滤器委托(delegate)。切勿为过滤器参数传递“null”。如果不应过滤订阅,则在需要弱事件引用时应使用传递过滤器委托(delegate)(典型场景):

EventAggregator.GetEvent().Subscribe(MyHandler, ThreadOption.PublisherThread, false, (dummy) => true);

以下缩写重载没有解决方法,并且在修补底层错误之前不应使用这些重载:

CompositePresentationEvent.Subscribe(操作操作) CompositePresentationEvent.Subscribe(Action 操作,ThreadOption threadOption) CompositePresentationEvent.Subscribe(Action 操作,bool keepSubscriberReferenceAlive) CompositePresentationEvent.Subscribe(Action action, ThreadOption threadOption, bool keepSubscriberReferenceAlive)

关于silverlight - 使用 Prism 进行事件订阅,给出方法访问异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1637720/

相关文章:

c# - Windows Phone 7 : Making ListBox items change dynamically

wpf - 数组按数据网格上的位置绑定(bind) Xaml

silverlight - 使用外部控件自定义 Silverlight Dataform 的命令

silverlight - 向 Silverlight 应用程序添加帮助系统的好方法是什么?

c# - 配置单例并将其公开给 MEF/PRISM 应用程序中的所有模块

c# - CAB 与 Prism 的比较

c# - 如何在不破坏 MVVM 的情况下导入我的 ViewModel?

c# - Xamarin Forms - Prism - OnNavigatedTo 调用两次

c# - 在应用程序中导航已激活的 Windows Phone 7(逻辑删除)

c# - Prism 5 - MVVM 框架