/// <summary> /// This is called when the parent link of the Visual is changed. /// This method executes important base functionality before calling the /// overridable virtual. /// </summary> /// <param name="oldParent">Old parent or null if the Visual did not have a parent before.</param> internal virtual void FireOnVisualParentChanged(DependencyObject oldParent) { // Call the ParentChanged virtual before firing the Ancestor Changed Event OnVisualParentChanged(oldParent); // If we are attaching to a tree then // send the bit up if we need to. if (oldParent == null) { Debug.Assert(VisualTreeHelper.GetParent(this) != null, "If oldParent is null, current parent should != null."); if(CheckFlagsAnd(VisualFlags.SubTreeHoldsAncestorChanged)) { Visual.SetTreeBits( VisualTreeHelper.GetParent(this), VisualFlags.SubTreeHoldsAncestorChanged, VisualFlags.RegisteredForAncestorChanged); } } // If we are cutting a sub tree off then // clear the bit in the main tree above if we need to. else { if (CheckFlagsAnd(VisualFlags.SubTreeHoldsAncestorChanged)) { Visual.ClearTreeBits( oldParent, VisualFlags.SubTreeHoldsAncestorChanged, VisualFlags.RegisteredForAncestorChanged); } } // Fire the Ancestor changed Event on the nodes. AncestorChangedEventArgs args = new AncestorChangedEventArgs(this, oldParent); ProcessAncestorChangedNotificationRecursive(this, args); }
/// <summary> /// Walks down in the tree for nodes that have AncestorChanged Handlers /// registered and calls them. /// It uses Flag bits that help it prune the walk. This should go /// straight to the relevent nodes. /// </summary> internal static void ProcessAncestorChangedNotificationRecursive(DependencyObject e, AncestorChangedEventArgs args) { if (e is Visual) { Visual.ProcessAncestorChangedNotificationRecursive(e, args); } else { Visual3D eAsVisual3D = e as Visual3D; // If the flag is not set, then we are Done. if(!eAsVisual3D.CheckFlagsAnd(VisualFlags.SubTreeHoldsAncestorChanged)) { return; } // If there is a handler on this node, then fire it. Visual.AncestorChangedEventHandler handler = AncestorChangedEventField.GetValue(eAsVisual3D); if(handler != null) { handler(eAsVisual3D, args); } // Decend into the children. int count = eAsVisual3D.InternalVisual2DOr3DChildrenCount; for (int i = 0; i < count; i++) { DependencyObject child = eAsVisual3D.InternalGet2DOr3DVisualChild(i); if (child != null) { Visual3D.ProcessAncestorChangedNotificationRecursive(child, args); } } } }
internal static void OnVisualAncestorChanged(DependencyObject uie, AncestorChangedEventArgs e) { Debug.Assert(InputElement.IsUIElement3D(uie) || InputElement.IsUIElement(uie)); if (true == (bool)uie.GetValue(GetsSourceChangedEventProperty)) { UpdateSourceOfElement(uie, e.Ancestor, e.OldParent); } }
internal void OnVisualAncestorChanged(object sender, AncestorChangedEventArgs e) { UIElement3D uie3D = sender as UIElement3D; if (null != uie3D) PresentationSource.OnVisualAncestorChanged(uie3D, e); }
private void OnVisualAncestorChanged_ForceInherit(object sender, AncestorChangedEventArgs e) { // NOTE: // // We are forced to listen to AncestorChanged events because // a UIElement may have raw Visuals between it and its nearest // UIElement parent. We only care about changes that happen // to the visual tree BETWEEN this UIElement and its nearest // UIElement parent. This is because we can rely on our // nearest UIElement parent to notify us when its force-inherit // properties change. DependencyObject parent = null; if (e.OldParent == null) { // We were plugged into something. // Find our nearest UIElement parent. parent = InputElement.GetContainingUIElement(InternalVisualParent); // See if this parent is a child of the ancestor who's parent changed. // If so, we don't care about changes that happen above us. if (parent != null && VisualTreeHelper.IsAncestorOf(e.Ancestor, parent)) { parent = null; } } else { // we were unplugged from something. // Find our nearest UIElement parent. parent = InputElement.GetContainingUIElement(InternalVisualParent); if (parent != null) { // If we found a UIElement parent in our subtree, the // break in the visual tree must have been above it, // so we don't need to respond. parent = null; } else { // There was no UIElement parent in our subtree, so we // may be detaching from some UIElement parent above // the break point in the tree. parent = InputElement.GetContainingUIElement(e.OldParent); } } if (parent != null) { UIElement.SynchronizeForceInheritProperties(null, null, this, parent); } }
internal new void OnVisualAncestorChanged(object sender, AncestorChangedEventArgs e) { // NOTE: // // We are forced to listen to AncestorChanged events because a FrameworkElement // may have raw Visuals/UIElements between it and its nearest FrameworkElement // parent. We only care about changes that happen to the visual tree BETWEEN // this FrameworkElement and its nearest FrameworkElement parent. This is // because we can rely on our nearest FrameworkElement parent to notify us // when its loaded state changes. FrameworkElement feParent = null; FrameworkContentElement fceParent = null; // Find our nearest FrameworkElement parent. FrameworkElement.GetContainingFrameworkElement(VisualTreeHelper.GetParent(this), out feParent, out fceParent); Debug.Assert(fceParent == null, "Nearest framework parent via the visual tree has to be an FE. It cannot be an FCE"); if(e.OldParent == null) { // We were plugged into something. // See if this parent is a child of the ancestor who's parent changed. // If so, we don't care about changes that happen above us. if(feParent == null || !VisualTreeHelper.IsAncestorOf(e.Ancestor, feParent)) { // Update HasLoadedChangeHandler Flag BroadcastEventHelper.AddOrRemoveHasLoadedChangeHandlerFlag(this, null, VisualTreeHelper.GetParent(e.Ancestor)); // Fire Loaded and Unloaded Events BroadcastEventHelper.BroadcastLoadedOrUnloadedEvent(this, null, VisualTreeHelper.GetParent(e.Ancestor)); } } else { // we were unplugged from something. // If we found a FrameworkElement parent in our subtree, the // break in the visual tree must have been above it, // so we don't need to respond. if(feParent == null) { // There was no FrameworkElement parent in our subtree, so we // may be detaching from some FrameworkElement parent above // the break point in the tree. FrameworkElement.GetContainingFrameworkElement(e.OldParent, out feParent, out fceParent); if(feParent != null) { // Update HasLoadedChangeHandler Flag BroadcastEventHelper.AddOrRemoveHasLoadedChangeHandlerFlag(this, feParent, null); // Fire Loaded and Unloaded Events BroadcastEventHelper.BroadcastLoadedOrUnloadedEvent(this, feParent, null); } } } }
internal new void OnVisualAncestorChanged(object sender, AncestorChangedEventArgs e) { FrameworkElement fe = (FrameworkElement) null; FrameworkContentElement fce = (FrameworkContentElement) null; FrameworkElement.GetContainingFrameworkElement(VisualTreeHelper.GetParent((DependencyObject) this), out fe, out fce); if (e.OldParent == null) { if (fe != null && VisualTreeHelper.IsAncestorOf(e.Ancestor, (DependencyObject) fe)) return; BroadcastEventHelper.AddOrRemoveHasLoadedChangeHandlerFlag((DependencyObject) this, (DependencyObject) null, VisualTreeHelper.GetParent(e.Ancestor)); BroadcastEventHelper.BroadcastLoadedOrUnloadedEvent((DependencyObject) this, (DependencyObject) null, VisualTreeHelper.GetParent(e.Ancestor)); } else { if (fe != null) return; FrameworkElement.GetContainingFrameworkElement(e.OldParent, out fe, out fce); if (fe == null) return; BroadcastEventHelper.AddOrRemoveHasLoadedChangeHandlerFlag((DependencyObject) this, (DependencyObject) fe, (DependencyObject) null); BroadcastEventHelper.BroadcastLoadedOrUnloadedEvent((DependencyObject) this, (DependencyObject) fe, (DependencyObject) null); } }