Ejemplo n.º 1
0
        public bool RaiseEvent(RoutedEventArgs e)
        {
            if (e.Stage == null)
            {
                e.Stage = Stage;
            }

            if (e.OriginalSource == null)
            {
                e.OriginalSource = this;
                e.Source         = this;
            }

            if (e.RoutedEvent.RoutingStrategy == RoutingStrategy.Direct)
            {
                EventManager.InvokeClassHandlers(this, e);
                if (!e.Stopped)
                {
                    InvokeHandler(e);
                }
                return(e.Cancelled);
            }

            // Collect ancestors so event propagation is unaffected by hierarchy changes.
            List <Group> ancestors = Pools <List <Group> > .Obtain();

            Group parent = Parent;

            while (parent != null)
            {
                ancestors.Add(parent);
                parent = parent.Parent;
            }

            try {
                if (e.RoutedEvent.RoutingStrategy == RoutingStrategy.Tunnel)
                {
                    // Notify all parent capture listeners, starting at the root. Ancestors may stop an event before children receive it.
                    for (int i = ancestors.Count - 1; i >= 0; i--)
                    {
                        Group currentTarget = ancestors[i];
                        EventManager.InvokeClassHandlers(currentTarget, e);
                        if (!e.Stopped)
                        {
                            currentTarget.InvokeHandler(e);
                        }
                        if (e.Stopped)
                        {
                            return(e.Cancelled);
                        }
                    }

                    EventManager.InvokeClassHandlers(this, e);
                    if (!e.Stopped)
                    {
                        InvokeHandler(e);
                    }
                    if (e.Stopped)
                    {
                        return(e.Cancelled);
                    }
                }
                else if (e.RoutedEvent.RoutingStrategy == RoutingStrategy.Bubble)
                {
                    EventManager.InvokeClassHandlers(this, e);
                    if (!e.Stopped)
                    {
                        InvokeHandler(e);
                    }
                    if (e.Stopped)
                    {
                        return(e.Cancelled);
                    }

                    // Notify all parent listeners, starting at the target. Children may stop an event before ancestors receive it.
                    foreach (Group ancestor in ancestors)
                    {
                        EventManager.InvokeClassHandlers(ancestor, e);
                        if (!e.Stopped)
                        {
                            ancestor.InvokeHandler(e);
                        }
                        if (e.Stopped)
                        {
                            return(e.Cancelled);
                        }
                    }
                }

                return(e.Cancelled);
            }
            finally {
                ancestors.Clear();
                Pools <List <Group> > .Release(ancestors);
            }
        }