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); } }