Exemplo n.º 1
0
        /// <summary>
        /// This method is an alternative to WPF's
        /// <see cref="VisualTreeHelper.GetParent"/> method, which also
        /// supports content elements. Keep in mind that for content element,
        /// this method falls back to the logical tree of the element!
        /// </summary>
        /// <param name="child">The item to be processed.</param>
        /// <returns>The submitted item's parent, if available. Otherwise
        /// null.</returns>
        public static DependencyObject GetParentObject(this DependencyObject child)
        {
            if (child == null)
            {
                return(null);
            }

            // handle content elements separately
            if (child is ContentElement contentElement)
            {
                DependencyObject parent = ContentOperations.GetParent(contentElement);
                if (parent != null)
                {
                    return(parent);
                }

                return(contentElement is FrameworkContentElement fce ? fce.Parent : null);
            }

            var childParent = VisualTreeHelper.GetParent(child);

            if (childParent != null)
            {
                return(childParent);
            }

            // also try searching for parent in framework elements (such as DockPanel, etc)
            if (child is FrameworkElement frameworkElement)
            {
                DependencyObject parent = frameworkElement.Parent;
                if (parent != null)
                {
                    return(parent);
                }
            }

            return(null);
        }
Exemplo n.º 2
0
        /// <summary>
        /// This method is an alternative to WPF's
        /// <see cref="VisualTreeHelper.GetParent"/> method, which also
        /// supports content elements. Keep in mind that for content element,
        /// this method falls back to the logical tree of the element!
        /// </summary>
        /// <param name="child">The item to be processed.</param>
        /// <returns>The submitted item's parent, if available. Otherwise
        /// null.</returns>
        public static DependencyObject GetParentObject(this DependencyObject child)
        {
            if (child == null)
            {
                return(null);
            }

#if !SILVERLIGHT
            //handle content elements separately
            var contentElement = child as ContentElement;
            if (contentElement != null)
            {
                DependencyObject parent = ContentOperations.GetParent(contentElement);
                if (parent != null)
                {
                    return(parent);
                }

                var fce = contentElement as FrameworkContentElement;
                return(fce != null ? fce.Parent : null);
            }
#endif

            // also try searching for parent in framework elements (such as DockPanel, etc)
            var frameworkElement = child as FrameworkElement;
            if (frameworkElement != null)
            {
                DependencyObject parent = frameworkElement.Parent;
                if (parent != null)
                {
                    return(parent);
                }
            }

            //if it's not a ContentElement/FrameworkElement, rely on VisualTreeHelper
            return(VisualTreeHelper.GetParent(child));
        }
        /// <summary>
        ///   This is a recursive function that walks up the tree Adding or Removing
        ///   HasLoadedChangeHander bits.   It also inits the IsLoadedCache on Add.
        /// </summary>
        /// <param name="d">
        ///     Node to update
        /// </param>
        /// <param name="addHandler">
        ///     Is it an AddHandler/ Add Child with Handler Operation
        /// </param>
        private static void UpdateHasLoadedChangeHandlerFlagInAncestry(DependencyObject d, bool addHandler)
        {
            FrameworkObject fo = new FrameworkObject(d);

            if (!addHandler)
            {
                if (AreThereLoadedChangeHandlersInSubtree(ref fo))
                {
                    return;  // done
                }
            }

            if (fo.IsValid)
            {
                if (fo.SubtreeHasLoadedChangeHandler != addHandler)
                {
                    DependencyObject coreParent    = (fo.IsFE) ? VisualTreeHelper.GetParent(fo.FE) : null;
                    DependencyObject logicalParent = fo.Parent;
                    DependencyObject parent        = null;

                    fo.SubtreeHasLoadedChangeHandler = addHandler;

                    // Propagate the change to your visual ancestry
                    if (coreParent != null)
                    {
                        UpdateHasLoadedChangeHandlerFlagInAncestry(coreParent, addHandler);
                        parent = coreParent;
                    }

                    // Propagate the change to your logical ancestry
                    if (logicalParent != null && logicalParent != coreParent)
                    {
                        UpdateHasLoadedChangeHandlerFlagInAncestry(logicalParent, addHandler);
                        if (fo.IsFCE)
                        {
                            parent = logicalParent;
                        }
                    }

                    // Propagate the change to your mentor, if any
                    if (logicalParent == null && coreParent == null)
                    {
                        parent = Helper.FindMentor(fo.DO.InheritanceContext);
                        if (parent != null)
                        {
                            fo.ChangeSubtreeHasLoadedChangedHandler(parent);
                        }
                    }

                    if (addHandler)
                    {
                        // The HasLoadedChangeHandler flag is used for two purposes.
                        // 1. To indicate that the sub-tree starting at the current node has
                        //    handlers for Loaded / Unloaded event.  So broadcast logic
                        //    can walk down that path to fire the events.
                        // 2. To indicate that the IsLoaded cache on the node is valid.

                        // If we are adding a handler:
                        // On the POP side of the recursion, as we come back down from the root,
                        // pull the value of IsLoadedCache from the parent in to the child.
                        if (fo.IsFE)
                        {
                            UpdateIsLoadedCache(fo.FE, parent);
                        }
                        else
                        {
                            UpdateIsLoadedCache(fo.FCE, parent);
                        }
                    }
                }
            }
            else  // neither a FE or an FCE
            {
                DependencyObject coreParent = null;
                Visual           v;
                Visual3D         v3D;
                ContentElement   ce;

                // This is neither an FE nor and FCE
                // Propagate the change to your visual ancestry
                if ((v = d as Visual) != null)
                {
                    coreParent = VisualTreeHelper.GetParent(v);
                }
                else if ((ce = d as ContentElement) != null)
                {
                    coreParent = ContentOperations.GetParent(ce);
                }
                else if ((v3D = d as Visual3D) != null)
                {
                    coreParent = VisualTreeHelper.GetParent(v3D);
                }

                if (coreParent != null)
                {
                    UpdateHasLoadedChangeHandlerFlagInAncestry(coreParent, addHandler);
                }
            }
        }
        // Token: 0x06000318 RID: 792 RVA: 0x00008B80 File Offset: 0x00006D80
        private static void UpdateHasLoadedChangeHandlerFlagInAncestry(DependencyObject d, bool addHandler)
        {
            FrameworkObject frameworkObject = new FrameworkObject(d);

            if (!addHandler && BroadcastEventHelper.AreThereLoadedChangeHandlersInSubtree(ref frameworkObject))
            {
                return;
            }
            if (frameworkObject.IsValid)
            {
                if (frameworkObject.SubtreeHasLoadedChangeHandler != addHandler)
                {
                    DependencyObject dependencyObject  = frameworkObject.IsFE ? VisualTreeHelper.GetParent(frameworkObject.FE) : null;
                    DependencyObject parent            = frameworkObject.Parent;
                    DependencyObject dependencyObject2 = null;
                    frameworkObject.SubtreeHasLoadedChangeHandler = addHandler;
                    if (dependencyObject != null)
                    {
                        BroadcastEventHelper.UpdateHasLoadedChangeHandlerFlagInAncestry(dependencyObject, addHandler);
                        dependencyObject2 = dependencyObject;
                    }
                    if (parent != null && parent != dependencyObject)
                    {
                        BroadcastEventHelper.UpdateHasLoadedChangeHandlerFlagInAncestry(parent, addHandler);
                        if (frameworkObject.IsFCE)
                        {
                            dependencyObject2 = parent;
                        }
                    }
                    if (parent == null && dependencyObject == null)
                    {
                        dependencyObject2 = Helper.FindMentor(frameworkObject.DO.InheritanceContext);
                        if (dependencyObject2 != null)
                        {
                            frameworkObject.ChangeSubtreeHasLoadedChangedHandler(dependencyObject2);
                        }
                    }
                    if (addHandler)
                    {
                        if (frameworkObject.IsFE)
                        {
                            BroadcastEventHelper.UpdateIsLoadedCache(frameworkObject.FE, dependencyObject2);
                            return;
                        }
                        BroadcastEventHelper.UpdateIsLoadedCache(frameworkObject.FCE, dependencyObject2);
                        return;
                    }
                }
            }
            else
            {
                DependencyObject dependencyObject3 = null;
                Visual           reference;
                ContentElement   reference2;
                Visual3D         reference3;
                if ((reference = (d as Visual)) != null)
                {
                    dependencyObject3 = VisualTreeHelper.GetParent(reference);
                }
                else if ((reference2 = (d as ContentElement)) != null)
                {
                    dependencyObject3 = ContentOperations.GetParent(reference2);
                }
                else if ((reference3 = (d as Visual3D)) != null)
                {
                    dependencyObject3 = VisualTreeHelper.GetParent(reference3);
                }
                if (dependencyObject3 != null)
                {
                    BroadcastEventHelper.UpdateHasLoadedChangeHandlerFlagInAncestry(dependencyObject3, addHandler);
                }
            }
        }