/// <summary>
        ///     Invokes all the handlers that have been
        ///     added to the route
        /// </summary>
        /// <remarks>
        ///     NOTE: If the <see cref="RoutingStrategy"/>
        ///     of the associated <see cref="RoutedEvent"/>
        ///     is <see cref="RoutingStrategy.Bubble"/>
        ///     the last handlers added are the
        ///     last ones invoked <para/>
        ///     However if the <see cref="RoutingStrategy"/>
        ///     of the associated <see cref="RoutedEvent"/>
        ///     is <see cref="RoutingStrategy.Tunnel"/>,
        ///     the last handlers added are the
        ///     first ones invoked.
        ///     However the handlers for a particular object
        ///     are always invoked in the order they were added
        ///     regardless of whether its a tunnel or buble.
        ///
        /// </remarks>
        /// <param name="source">
        ///     <see cref="RoutedEventArgs.Source"/>
        ///     that raised the RoutedEvent
        /// </param>
        /// <param name="args">
        ///     <see cref="RoutedEventArgs"/> that carry
        ///     all the details specific to this RoutedEvent
        /// </param>
        internal void InvokeHandlers(object source, RoutedEventArgs args)
        {
            // Check RoutingStrategy to know the order of invocation
            if (args.RoutedEvent.RoutingStrategy == RoutingStrategy.Bubble ||
                args.RoutedEvent.RoutingStrategy == RoutingStrategy.Direct)
            {
                // If the RoutingStrategy of the associated is
                // Bubble the handlers for the last target
                // added are the last ones invoked
                // Invoke class listeners
                for (int i = 0, count = _routeItemList.Count; i < count; i++)
                {
                    RouteItem ri = ((RouteItem)_routeItemList[i]);
                    args.InvokeHandler(ri);
                }
            }
            else
            {
                int endTargetIndex = _routeItemList.Count - 1;
                int startTargetIndex;

                // If the RoutingStrategy of the associated is
                // Tunnel the handlers for the last target
                // added are the first ones invoked
                while (endTargetIndex >= 0)
                {
                    // For tunnel events we need to invoke handlers for the last target first.
                    // However the handlers for that individual target must be fired in the right order.
                    object currTarget = ((RouteItem)_routeItemList[endTargetIndex]).Target;
                    for (startTargetIndex = endTargetIndex; startTargetIndex >= 0; startTargetIndex--)
                    {
                        if (((RouteItem)_routeItemList[startTargetIndex]).Target != currTarget)
                        {
                            if (startTargetIndex == endTargetIndex && endTargetIndex > 0)
                            {
                                endTargetIndex--;
                            }
                            else
                            {
                                break;
                            }
                        }
                    }

                    for (int i = startTargetIndex + 1; i <= endTargetIndex; i++)
                    {
                        RouteItem ri = ((RouteItem)_routeItemList[i]);
                        args.InvokeHandler(ri);
                    }

                    endTargetIndex = startTargetIndex;
                }
            }
        }
示例#2
0
        /// <summary>
        ///     Invokes all the handlers that have been
        ///     added to the route
        /// </summary>
        /// <remarks>
        ///     NOTE: If the <see cref="RoutingStrategy"/>
        ///     of the associated <see cref="RoutedEvent"/>
        ///     is <see cref="RoutingStrategy.Bubble"/>
        ///     the last handlers added are the
        ///     last ones invoked <para/>
        ///     However if the <see cref="RoutingStrategy"/>
        ///     of the associated <see cref="RoutedEvent"/>
        ///     is <see cref="RoutingStrategy.Tunnel"/>,
        ///     the last handlers added are the
        ///     first ones invoked.
        ///     However the handlers for a particular object
        ///     are always invoked in the order they were added
        ///     regardless of whether its a tunnel or buble.
        ///
        /// </remarks>
        /// <param name="source">
        ///     <see cref="RoutedEventArgs.Source"/>
        ///     that raised the RoutedEvent
        /// </param>
        /// <param name="args">
        ///     <see cref="RoutedEventArgs"/> that carry
        ///     all the details specific to this RoutedEvent
        /// </param>
        internal void InvokeHandlers(object source, RoutedEventArgs args)
        {
            // Check RoutingStrategy to know the order of invocation
            if (args.RoutedEvent.RoutingStrategy == RoutingStrategy.Bubble ||
                args.RoutedEvent.RoutingStrategy == RoutingStrategy.Direct)
            {

                // If the RoutingStrategy of the associated is
                // Bubble the handlers for the last target
                // added are the last ones invoked
                // Invoke class listeners
                for (int i = 0, count = _routeItemList.Count; i < count; i++)
                {
                    RouteItem ri = ((RouteItem)_routeItemList[i]);
                    args.InvokeHandler(ri);
                }
            }
            else
            {
                int endTargetIndex = _routeItemList.Count - 1;
                int startTargetIndex;

                // If the RoutingStrategy of the associated is
                // Tunnel the handlers for the last target
                // added are the first ones invoked
                while (endTargetIndex >= 0)
                {
                    // For tunnel events we need to invoke handlers for the last target first.
                    // However the handlers for that individual target must be fired in the right order.
                    object currTarget = ((RouteItem)_routeItemList[endTargetIndex]).Target;
                    for (startTargetIndex = endTargetIndex; startTargetIndex >= 0; startTargetIndex--)
                    {
                        if (((RouteItem)_routeItemList[startTargetIndex]).Target != currTarget)
                        {
                            if(startTargetIndex == endTargetIndex && endTargetIndex > 0)
                            {
                                endTargetIndex--;
                            }
                            else
                            {
                                break;
                            }
                        }
                    }

                    for (int i = startTargetIndex + 1; i <= endTargetIndex; i++)
                    {
                        RouteItem ri = ((RouteItem)_routeItemList[i]);
                        args.InvokeHandler(ri);
                    }

                    endTargetIndex = startTargetIndex;
                }
            }
        }