2

我正在创建一个 Windows Mobile 应用程序,并且在使用EventPublication.

我的订阅位于容器的主目录上,而发布位于从 OpenNETCF.IoC.UI.SmartPart 继承的对象上

应用程序启动

Public Class Startup
    Inherits SmartClientApplication(Of MainContainer)

    Public Shared Sub Main()
        Dim appStarter As New Startup
        appStarter.Start()
    End Sub

End Class

订阅 MainContiner 表单

<EventSubscription(EventNames.Navigate, ThreadOption.UserInterface)> _
Public Sub NavigateSmartPart(ByVal sender As Object, ByVal e As GenericEventArgs(Of String))
     .....
End Sub

出版商

Namespace Views

    Public Class ViewLogon

        <EventPublication(EventNames.Navigate)> _
        Friend Event NavigateToSmartPart As EventHandler(Of GenericEventArgs(Of String))

        Public Overrides Sub OnActivated()
        End Sub

    End Class

End Namespace

问题

如果我尝试编写这个聪明的部分,我在OpenNETCF.IoC.ObjectFactory.AddCollectionEventHandlers<TKey, TItem>方法中得到 NullReferenceException 就 source.EventInfo.AddEventHandler(instance, intermediate);行了。

删除EventPublication作品没有任何问题。

        private static void AddCollectionEventHandlers<TKey, TItem>(object instance, IEnumerable<KeyValuePair<TKey, TItem>> collection, PublicationDescriptor[] sourceEvents, SubscriptionDescriptor[] eventSinks)
        {
            if (collection == null) return;

            var invokerControl = RootWorkItem.Items.Get<TheInvoker>("IOCEventInvoker");

            foreach (var item in collection)
            {
                if (instance.Equals(item.Value)) continue;

                if((item.Value is WorkItem) && (collection is ServiceCollection))
                {
                    // this prevents recursion (and a stack overflow) for WorkItems
                    continue;
                }

                foreach (var source in sourceEvents)
                {
                    // wire up events
                    foreach (var sink in GetEventSinksFromTypeByName(item.Value.GetType(), source.Publication.EventName, ThreadOption.Caller))
                    {
                        Delegate d = Delegate.CreateDelegate(source.EventInfo.EventHandlerType, item.Value, sink);
                        source.EventInfo.AddEventHandler(instance, d);
                    }

                    foreach (var sink in GetEventSinksFromTypeByName(item.Value.GetType(), source.Publication.EventName, ThreadOption.UserInterface))
                    {
                        // wire up event handlers on the UI thread
                        Delegate d = Delegate.CreateDelegate(source.EventInfo.EventHandlerType, item.Value, sink);

                        if (source.EventInfo.EventHandlerType == typeof(EventHandler))
                        {
                            // unsure why so far but this fails if the EventHandler signature takes a subclass of EventArgs as the second param
                            // and if you use just EventArgs, the arg data gets lost
                            BasicInvoker invoker = new BasicInvoker(invokerControl, d);
                            Delegate intermediate = Delegate.CreateDelegate(source.EventInfo.EventHandlerType, invoker, invoker.HandlerMethod);
                            source.EventInfo.AddEventHandler(instance, intermediate);
                        }
                        else if ((source.EventInfo.EventHandlerType.IsGenericType) && (source.EventInfo.EventHandlerType.GetGenericTypeDefinition().Name == "EventHandler`1"))
                        {
                            BasicInvoker invoker = new BasicInvoker(invokerControl, d);
                            Delegate intermediate = Delegate.CreateDelegate(source.EventInfo.EventHandlerType, invoker, invoker.HandlerMethod);
                            source.EventInfo.AddEventHandler(instance, intermediate);
                        }

                    }
                }

                // back-wire any sinks
                foreach (var sink in eventSinks)
                {
                    foreach (var ei in GetEventSourcesFromTypeByName(item.Value.GetType(), sink.Subscription.EventName))
                    {
                        try
                        {
                            // (type, consumer instance, consumer method)
                            Delegate d = Delegate.CreateDelegate(ei.EventHandlerType, instance, sink.MethodInfo);

                            if (sink.Subscription.ThreadOption == ThreadOption.Caller)
                            {
                                ei.AddEventHandler(item.Value, d);
                            }
                            else
                            {
                                // wire up event handlers on the UI thread
                                if ((ei.EventHandlerType.IsGenericType) && (ei.EventHandlerType.GetGenericTypeDefinition().Name == "EventHandler`1")
                                    || (ei.EventHandlerType == typeof(EventHandler))
#if !WINDOWS_PHONE
                                    || (ei.EventHandlerType == typeof(KeyEventHandler))
#endif


                      )
                            {
                                // unsure why so far but this fails if the EventHandler signature takes a subclass of EventArgs as the second param
                                // and if you use just EventArgs, the arg data gets lost


                                BasicInvoker invoker = new BasicInvoker(invokerControl, d);
                                Delegate intermediate = Delegate.CreateDelegate(ei.EventHandlerType, invoker, invoker.HandlerMethod);
                                ei.AddEventHandler(item.Value, intermediate);
                            }
                            else
                            {
                                throw new ArgumentException("ThreadOption.UserInterface only supported for EventHandler and EventHandler<T> events");
                            }
                        }
                    }
                    catch (ArgumentException)
                    {
                        throw new ArgumentException(string.Format("Unable to attach EventHandler '{0}' to '{1}'.\r\nDo the publisher and subscriber signatures match?", ei.Name, instance.GetType().Name));
                    }
                }
            }

            WorkItem wi = item.Value as WorkItem;
            if (wi != null)
            {
                AddEventHandlers(instance, wi, false);
            }
        }
    }

堆栈跟踪

   at System.Reflection.EventInfo.AddEventHandler(Object target, Delegate handler)
   at OpenNETCF.IoC.ObjectFactory.AddCollectionEventHandlers[TKey,TItem](Object instance, IEnumerable`1 collection, PublicationDescriptor[] sourceEvents, SubscriptionDescriptor[] eventSinks)
   at OpenNETCF.IoC.ObjectFactory.AddEventHandlers(Object instance, WorkItem root, Boolean walkUpToRoot)
   at OpenNETCF.IoC.ObjectFactory.AddEventHandlers(Object instance, WorkItem root)
   at OpenNETCF.IoC.ObjectFactory.DoInjections(Object instance, WorkItem root)
   at OpenNETCF.IoC.ManagedObjectCollection`1.Add(ISmartPart item, String id, Boolean expectNullId)
   at OpenNETCF.IoC.ManagedObjectCollection`1.AddNew(Type typeToBuild, String id, Boolean expectNullId, Boolean wrapDisposables)
   at OpenNETCF.IoC.ManagedObjectCollection`1.AddNew(Type typeToBuild, String id)
   at OpenNETCF.IoC.ManagedObjectCollection`1.AddNew[TTypeToBuild](String id)
   at StockMovement.IoC.Container.RegisterViews()
   at StockMovement.IoC.Container.RegisterParts(DeckWorkspace workspace)
   at StockMovement.MainContainer.MainContainerLoad(Object sender, EventArgs e)
   at System.Windows.Forms.Form.OnLoad(EventArgs e)
   at System.Windows.Forms.Form._SetVisibleNotify(Boolean fVis)
   at System.Windows.Forms.Control.set_Visible(Boolean value)
   at System.Windows.Forms.Application.Run(Form fm)
   at OpenNETCF.IoC.UI.SmartClientApplication`1.OnApplicationRun(Form form)
   at OpenNETCF.IoC.UI.SmartClientApplication`1.Start(IModuleInfoStore store)
   at OpenNETCF.IoC.UI.SmartClientApplication`1.Start()
   at StockMovement.Startup.Main()
4

1 回答 1

1

好的,幸运的是,我已经弄清楚了。然后事件需要公开才能连接发布/订阅。

<EventPublication(EventNames.Navigate)> _
Friend Event NavigateToSmartPart As EventHandler(Of GenericEventArgs(Of String))

更改为以下工作。

<EventPublication(EventNames.Navigate)> _
Public Event NavigateToSmartPart As EventHandler(Of GenericEventArgs(Of String))
于 2013-06-24T10:12:28.153 回答