/// <summary> /// Allows FrameworkElement to augment the /// <see cref="EventRoute"/> /// </summary> /// <remarks> /// NOTE: If this instance does not have a /// visualParent but has a model parent /// then route is built through the model /// parent /// </remarks> /// <param name="route"> /// The <see cref="EventRoute"/> to be /// augmented /// </param> /// <param name="args"> /// <see cref="RoutedEventArgs"/> for the /// RoutedEvent to be raised post building /// the route /// </param> /// <returns> /// Whether or not the route should continue past the visual tree. /// If this is true, and there are no more visual parents, the route /// building code will call the GetUIParentCore method to find the /// next non-visual parent. /// </returns> internal override sealed bool BuildRouteCore(EventRoute route, RoutedEventArgs args) { bool continuePastCoreTree = false; // Verify Context Access // VerifyAccess(); DependencyObject visualParent = (DependencyObject) ContentOperations.GetParent(this); DependencyObject modelParent = this._parent; // FrameworkElement extends the basic event routing strategy by // introducing the concept of a logical tree. When an event // passes through an element in a logical tree, the source of // the event needs to change to the leaf-most node in the same // logical tree that is in the route. // Check the route to see if we are returning into a logical tree // that we left before. If so, restore the source of the event to // be the source that it was when we left the logical tree. DependencyObject branchNode = route.PeekBranchNode() as DependencyObject; if (branchNode != null && IsLogicalDescendent(branchNode)) { // We keep the most recent source in the event args. Note that // this is only for our consumption. Once the event is raised, // it will use the source information in the route. args.Source = (route.PeekBranchSource()); AdjustBranchSource(args); route.AddSource(args.Source); // By popping the branch node we will also be setting the source // in the event route. route.PopBranchNode(); // Add intermediate ContentElements to the route FrameworkElement.AddIntermediateElementsToRoute(this, route, args, LogicalTreeHelper.GetParent(branchNode)); } // Check if the next element in the route is in a different // logical tree. if (!IgnoreModelParentBuildRoute(args)) { // If there is no visual parent, route via the model tree. if (visualParent == null) { continuePastCoreTree = modelParent != null; } else if(modelParent != null) { // If there is a model parent, record the branch node. route.PushBranchNode(this, args.Source); // The source is going to be the visual parent, which // could live in a different logical tree. args.Source = (visualParent); } } return continuePastCoreTree; }
internal bool BuildRouteCoreHelper(EventRoute route, RoutedEventArgs args, bool shouldAddIntermediateElementsToRoute) { bool flag = false; DependencyObject parent = VisualTreeHelper.GetParent((DependencyObject) this); DependencyObject uiParentCore = this.GetUIParentCore(); DependencyObject dependencyObject = route.PeekBranchNode() as DependencyObject; if (dependencyObject != null && this.IsLogicalDescendent(dependencyObject)) { args.Source = route.PeekBranchSource(); this.AdjustBranchSource(args); route.AddSource(args.Source); route.PopBranchNode(); if (shouldAddIntermediateElementsToRoute) FrameworkElement.AddIntermediateElementsToRoute((DependencyObject) this, route, args, LogicalTreeHelper.GetParent(dependencyObject)); } if (!this.IgnoreModelParentBuildRoute(args)) { if (parent == null) flag = uiParentCore != null; else if (uiParentCore != null) { Visual visual = parent as Visual; if (visual != null) { if (visual.CheckFlagsAnd(VisualFlags.IsLayoutIslandRoot)) flag = true; } else if (((Visual3D) parent).CheckFlagsAnd(VisualFlags.IsLayoutIslandRoot)) flag = true; route.PushBranchNode((object) this, args.Source); args.Source = (object) parent; } } return flag; }