VisualTreeUtils.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / Tools / System.Activities.Presentation / System / Activities / Presentation / Base / Core / Internal / PropertyEditing / VisualTreeUtils.cs / 1305376 / VisualTreeUtils.cs

                            //---------------------------------------------------------------- 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//---------------------------------------------------------------
namespace System.Activities.Presentation.Internal.PropertyEditing
{ 
    using System;
    using System.Collections; 
    using System.Diagnostics.CodeAnalysis; 
    using System.Windows;
    using System.Windows.Media; 
    using System.Windows.Media.Media3D;
    using System.Collections.Generic;

    //  
    // Collection of simple utilities that deal with the VisualTree
    //  
    internal static class VisualTreeUtils 
    {
 
        // The depth of the visual tree we explore in looking for templated children
        // (see GetTemplateChild<>())
        private const int MaxSearchDepth = 5;
 
        // The maxium wpf visual tree depth
        // this value should be kept in [....] with WPF's limit 
        private const int MaxAllowedTreeDepth = 250; 

        //  
        // Examines the visual children of the given element and returns the one
        // with the specified name and type, if one exists
        // 
        // Type of child to look for 
        // Container to look in
        // Name to look for 
        // The specified named child if found, null otherwise 
        public static T GetNamedChild(DependencyObject container, string name)
            where T : FrameworkElement 
        {
            return GetNamedChild(container, name, 0);
        }
 
        // 
        // Examines the visual children of the given element and returns the one 
        // with the specified name and type, if one exists 
        // 
        // Type of child to look for 
        // Container to look in
        // Name to look for
        // Visual depth to search in.  Default is 0.
        // The specified named child if found, null otherwise 
        public static T GetNamedChild(DependencyObject container, string name, int searchDepth)
            where T : FrameworkElement 
        { 
            if (container == null || string.IsNullOrEmpty(name) || searchDepth < 0)
            { 
                return null;
            }

            if (container is T && string.Equals( name, ((T)container).Name)) 
            {
                return (T)container; 
            } 

            int childCount = VisualTreeHelper.GetChildrenCount(container); 
            if (childCount == 0)
            {
                return null;
            } 

            // Look for the first child that matches 
            for (int index = 0; index < childCount; index++) 
            {
                FrameworkElement child = VisualTreeHelper.GetChild(container, index) as FrameworkElement; 
                if (child == null)
                {
                    continue;
                } 

                // Search recursively until we reach the requested search depth 
                T namedChild = 
                    (child.FindName(name) as T) ??
                    (searchDepth > 0 ? GetNamedChild(child, name, searchDepth - 1) : null); 

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

        // 
        // Helper method that goes down the first-child visual tree and looks for the visual element of the
        // specified type.  Useful for when you have one control that is templated to look like another 
        // and you need to get to the template instance itself.
        //  
        // Type of the visual template to look for 
        // Element to start from
        // The first matching instance in the visual tree of first children, null otherwise 
        public static T GetTemplateChild(DependencyObject element) where T : DependencyObject
        {
            int availableSearchDepth = MaxSearchDepth;
            while (availableSearchDepth > 0 && element != null) 
            {
                int childrenCount = VisualTreeHelper.GetChildrenCount(element); 
                if (childrenCount < 1) 
                {
                    return null; 
                }

                // Just worry about the first child, since we are looking for a template control,
                // not a complicated visual tree 
                //
                element = VisualTreeHelper.GetChild(element, 0); 
                T childAsT = element as T; 
                if (childAsT != null)
                { 
                    return childAsT;
                }

                availableSearchDepth--; 
            }
 
            return null; 
        }
 
        // 
        // Goes up the visual tree, looking for an ancestor of the specified Type
        // 
        // Type to look for 
        // Starting point
        // Visual ancestor, if any, of the specified starting point and Type 
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 
        public static T FindVisualAncestor(DependencyObject child) where T : DependencyObject
        { 
            if (child == null)
            {
                return null;
            } 

            do 
            { 
                child = VisualTreeHelper.GetParent(child);
            } 
            while (child != null && !typeof(T).IsAssignableFrom(child.GetType()));

            return child as T;
        } 

        //  
        // Recursively looks through all the children and looks for and returns the first 
        // element with IsFocusable set to true.
        //  
        // Starting point for the search
        // Type of child to look for
        // The first focusable child of the specified Type, null otherwise.
        public static T FindFocusableElement(T reference) where T : UIElement 
        {
            if (reference == null || (reference.Focusable && reference.Visibility == Visibility.Visible)) 
            { 
                return reference;
            } 

            int childCount = VisualTreeHelper.GetChildrenCount(reference);
            for (int i = 0; i < childCount; i++)
            { 
                T child = VisualTreeHelper.GetChild(reference, i) as T;
                if (child == null) 
                { 
                    continue;
                } 

                if (child.Visibility != Visibility.Visible)
                {
                    continue; 
                }
 
                if (child.Focusable) 
                {
                    return child; 
                }

                child = FindFocusableElement(child);
                if (child != null) 
                {
                    return child; 
                } 
            }
 
            return null;
        }

        //  
        // Walks up the parent tree and returns the first
        // element with IsFocusable set to true. 
        //  
        // Starting point for the search
        // Type of parent to look for 
        // The first focusable parent of the specified Type, null otherwise.
        public static T FindFocusableParent(UIElement reference) where T : UIElement
        {
            if (null != reference) 
            {
                UIElement parent = VisualTreeHelper.GetParent(reference) as UIElement; 
                while (null != parent) 
                {
                    if (parent.Visibility == Visibility.Visible && parent is T && parent.Focusable) 
                    {
                        return parent as T;
                    }
 
                    parent = VisualTreeHelper.GetParent(parent) as UIElement;
                } 
            } 
            return null;
        } 

        // 
        // Helper method identical to VisualTreeHelper.GetParent() but that also returns the index of the given child
        // with respect to any of its visual siblings 
        // 
        // Child to examine 
        // Total number of children that the specified child's parent has 
        // Index of the specified child in the parent's visual children array
        // Visual parent of the specified child, if any 
        public static DependencyObject GetIndexedVisualParent(DependencyObject child, out int childrenCount, out int childIndex)
        {
            childrenCount = 0;
            DependencyObject parent = VisualTreeHelper.GetParent(child); 

            if (parent != null) 
            { 
                childrenCount = VisualTreeHelper.GetChildrenCount(parent);
                for (childIndex = 0; childIndex < childrenCount; childIndex++) 
                {
                    if (child.Equals(VisualTreeHelper.GetChild(parent, childIndex)))
                    {
                        return parent; 
                    }
                } 
            } 

            childIndex = -1; 
            return null;
        }

        //  
        // Helper method that goes up the visual tree checking the visibility flag of the specified element
        // and all its parents.  If an invisible parent is found, the method return false.  Otherwise it returns 
        // true. 
        // 
        // Element to check 
        // True if the specified element and all of its visual parents are visible,
        // false otherwise.
        public static bool IsVisible(UIElement element)
        { 
            UIElement parent = element;
            while (parent != null) 
            { 
                if (parent.Visibility != Visibility.Visible)
                { 
                    return false;
                }

                parent = VisualTreeHelper.GetParent(parent) as UIElement; 
            }
 
            return true; 
        }
 
        /// 
        /// Helper method that trasverse the visual tree checking for immediate parent of specified type that has children
        /// that is too deep for WPF visual tree
        ///  
        /// The type of parent to look for
        /// The root element to start checking 
        ///  
        public static ICollection PrunVisualTree(Visual root) where T : DependencyObject
        { 
            HashSet deepElements = new HashSet();
            Stack stack = new Stack();
            VisualState currentObject = new VisualState(root, GetTreeDepth(root));
            stack.Push(currentObject); 
            int totalChildCount = 0;
            Visual child; 
            T violatingParent; 
            //doing a depth first walk of the visual tree.
            while (stack.Count > 0) 
            {
                currentObject = stack.Pop();

                // currentObject.Depth + 1 is the children's depth 
                // if it's too deep, we would try to find the parent and stop traversing
                // this node further 
                if (currentObject.Depth + 1 >= MaxAllowedTreeDepth) 
                {
                    violatingParent = currentObject.Visual as T; 
                    if (violatingParent != null)
                    {
                        deepElements.Add(violatingParent);
                    } 
                    else
                    { 
                        violatingParent = FindVisualAncestor(currentObject.Visual); 
                        if (violatingParent != null)
                        { 
                            deepElements.Add(violatingParent);
                        }
                    }
                } 
                else // continue the depth first traversal
                { 
                    totalChildCount = VisualTreeHelper.GetChildrenCount(currentObject.Visual); 
                    for (int i = 0; i < totalChildCount; i++)
                    { 
                        child = VisualTreeHelper.GetChild(currentObject.Visual, i) as Visual;
                        if (child != null)
                        {
                            stack.Push(new VisualState(child, currentObject.Depth + 1)); 
                        }
                    } 
                } 
            }
           return deepElements; 
        }

        //find the depth of an DependencyObject
        public static uint GetTreeDepth(DependencyObject element) 
        {
            uint depth = 0; 
            while (element != null) 
            {
                depth++; 
                if (element is Visual || element is Visual3D)
                {
                    element = VisualTreeHelper.GetParent(element);
                } 
                else
                { 
                    element = LogicalTreeHelper.GetParent(element); 
                }
            } 
            return depth;
        }

        private class VisualState 
        {
            internal Visual Visual { get; set; } 
            internal uint Depth { get; set; } 

            internal VisualState(Visual visual, uint depth) 
            {
                this.Visual = visual;
                this.Depth = depth;
            } 
        }
    } 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//---------------------------------------------------------------- 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//---------------------------------------------------------------
namespace System.Activities.Presentation.Internal.PropertyEditing
{ 
    using System;
    using System.Collections; 
    using System.Diagnostics.CodeAnalysis; 
    using System.Windows;
    using System.Windows.Media; 
    using System.Windows.Media.Media3D;
    using System.Collections.Generic;

    //  
    // Collection of simple utilities that deal with the VisualTree
    //  
    internal static class VisualTreeUtils 
    {
 
        // The depth of the visual tree we explore in looking for templated children
        // (see GetTemplateChild<>())
        private const int MaxSearchDepth = 5;
 
        // The maxium wpf visual tree depth
        // this value should be kept in [....] with WPF's limit 
        private const int MaxAllowedTreeDepth = 250; 

        //  
        // Examines the visual children of the given element and returns the one
        // with the specified name and type, if one exists
        // 
        // Type of child to look for 
        // Container to look in
        // Name to look for 
        // The specified named child if found, null otherwise 
        public static T GetNamedChild(DependencyObject container, string name)
            where T : FrameworkElement 
        {
            return GetNamedChild(container, name, 0);
        }
 
        // 
        // Examines the visual children of the given element and returns the one 
        // with the specified name and type, if one exists 
        // 
        // Type of child to look for 
        // Container to look in
        // Name to look for
        // Visual depth to search in.  Default is 0.
        // The specified named child if found, null otherwise 
        public static T GetNamedChild(DependencyObject container, string name, int searchDepth)
            where T : FrameworkElement 
        { 
            if (container == null || string.IsNullOrEmpty(name) || searchDepth < 0)
            { 
                return null;
            }

            if (container is T && string.Equals( name, ((T)container).Name)) 
            {
                return (T)container; 
            } 

            int childCount = VisualTreeHelper.GetChildrenCount(container); 
            if (childCount == 0)
            {
                return null;
            } 

            // Look for the first child that matches 
            for (int index = 0; index < childCount; index++) 
            {
                FrameworkElement child = VisualTreeHelper.GetChild(container, index) as FrameworkElement; 
                if (child == null)
                {
                    continue;
                } 

                // Search recursively until we reach the requested search depth 
                T namedChild = 
                    (child.FindName(name) as T) ??
                    (searchDepth > 0 ? GetNamedChild(child, name, searchDepth - 1) : null); 

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

        // 
        // Helper method that goes down the first-child visual tree and looks for the visual element of the
        // specified type.  Useful for when you have one control that is templated to look like another 
        // and you need to get to the template instance itself.
        //  
        // Type of the visual template to look for 
        // Element to start from
        // The first matching instance in the visual tree of first children, null otherwise 
        public static T GetTemplateChild(DependencyObject element) where T : DependencyObject
        {
            int availableSearchDepth = MaxSearchDepth;
            while (availableSearchDepth > 0 && element != null) 
            {
                int childrenCount = VisualTreeHelper.GetChildrenCount(element); 
                if (childrenCount < 1) 
                {
                    return null; 
                }

                // Just worry about the first child, since we are looking for a template control,
                // not a complicated visual tree 
                //
                element = VisualTreeHelper.GetChild(element, 0); 
                T childAsT = element as T; 
                if (childAsT != null)
                { 
                    return childAsT;
                }

                availableSearchDepth--; 
            }
 
            return null; 
        }
 
        // 
        // Goes up the visual tree, looking for an ancestor of the specified Type
        // 
        // Type to look for 
        // Starting point
        // Visual ancestor, if any, of the specified starting point and Type 
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 
        public static T FindVisualAncestor(DependencyObject child) where T : DependencyObject
        { 
            if (child == null)
            {
                return null;
            } 

            do 
            { 
                child = VisualTreeHelper.GetParent(child);
            } 
            while (child != null && !typeof(T).IsAssignableFrom(child.GetType()));

            return child as T;
        } 

        //  
        // Recursively looks through all the children and looks for and returns the first 
        // element with IsFocusable set to true.
        //  
        // Starting point for the search
        // Type of child to look for
        // The first focusable child of the specified Type, null otherwise.
        public static T FindFocusableElement(T reference) where T : UIElement 
        {
            if (reference == null || (reference.Focusable && reference.Visibility == Visibility.Visible)) 
            { 
                return reference;
            } 

            int childCount = VisualTreeHelper.GetChildrenCount(reference);
            for (int i = 0; i < childCount; i++)
            { 
                T child = VisualTreeHelper.GetChild(reference, i) as T;
                if (child == null) 
                { 
                    continue;
                } 

                if (child.Visibility != Visibility.Visible)
                {
                    continue; 
                }
 
                if (child.Focusable) 
                {
                    return child; 
                }

                child = FindFocusableElement(child);
                if (child != null) 
                {
                    return child; 
                } 
            }
 
            return null;
        }

        //  
        // Walks up the parent tree and returns the first
        // element with IsFocusable set to true. 
        //  
        // Starting point for the search
        // Type of parent to look for 
        // The first focusable parent of the specified Type, null otherwise.
        public static T FindFocusableParent(UIElement reference) where T : UIElement
        {
            if (null != reference) 
            {
                UIElement parent = VisualTreeHelper.GetParent(reference) as UIElement; 
                while (null != parent) 
                {
                    if (parent.Visibility == Visibility.Visible && parent is T && parent.Focusable) 
                    {
                        return parent as T;
                    }
 
                    parent = VisualTreeHelper.GetParent(parent) as UIElement;
                } 
            } 
            return null;
        } 

        // 
        // Helper method identical to VisualTreeHelper.GetParent() but that also returns the index of the given child
        // with respect to any of its visual siblings 
        // 
        // Child to examine 
        // Total number of children that the specified child's parent has 
        // Index of the specified child in the parent's visual children array
        // Visual parent of the specified child, if any 
        public static DependencyObject GetIndexedVisualParent(DependencyObject child, out int childrenCount, out int childIndex)
        {
            childrenCount = 0;
            DependencyObject parent = VisualTreeHelper.GetParent(child); 

            if (parent != null) 
            { 
                childrenCount = VisualTreeHelper.GetChildrenCount(parent);
                for (childIndex = 0; childIndex < childrenCount; childIndex++) 
                {
                    if (child.Equals(VisualTreeHelper.GetChild(parent, childIndex)))
                    {
                        return parent; 
                    }
                } 
            } 

            childIndex = -1; 
            return null;
        }

        //  
        // Helper method that goes up the visual tree checking the visibility flag of the specified element
        // and all its parents.  If an invisible parent is found, the method return false.  Otherwise it returns 
        // true. 
        // 
        // Element to check 
        // True if the specified element and all of its visual parents are visible,
        // false otherwise.
        public static bool IsVisible(UIElement element)
        { 
            UIElement parent = element;
            while (parent != null) 
            { 
                if (parent.Visibility != Visibility.Visible)
                { 
                    return false;
                }

                parent = VisualTreeHelper.GetParent(parent) as UIElement; 
            }
 
            return true; 
        }
 
        /// 
        /// Helper method that trasverse the visual tree checking for immediate parent of specified type that has children
        /// that is too deep for WPF visual tree
        ///  
        /// The type of parent to look for
        /// The root element to start checking 
        ///  
        public static ICollection PrunVisualTree(Visual root) where T : DependencyObject
        { 
            HashSet deepElements = new HashSet();
            Stack stack = new Stack();
            VisualState currentObject = new VisualState(root, GetTreeDepth(root));
            stack.Push(currentObject); 
            int totalChildCount = 0;
            Visual child; 
            T violatingParent; 
            //doing a depth first walk of the visual tree.
            while (stack.Count > 0) 
            {
                currentObject = stack.Pop();

                // currentObject.Depth + 1 is the children's depth 
                // if it's too deep, we would try to find the parent and stop traversing
                // this node further 
                if (currentObject.Depth + 1 >= MaxAllowedTreeDepth) 
                {
                    violatingParent = currentObject.Visual as T; 
                    if (violatingParent != null)
                    {
                        deepElements.Add(violatingParent);
                    } 
                    else
                    { 
                        violatingParent = FindVisualAncestor(currentObject.Visual); 
                        if (violatingParent != null)
                        { 
                            deepElements.Add(violatingParent);
                        }
                    }
                } 
                else // continue the depth first traversal
                { 
                    totalChildCount = VisualTreeHelper.GetChildrenCount(currentObject.Visual); 
                    for (int i = 0; i < totalChildCount; i++)
                    { 
                        child = VisualTreeHelper.GetChild(currentObject.Visual, i) as Visual;
                        if (child != null)
                        {
                            stack.Push(new VisualState(child, currentObject.Depth + 1)); 
                        }
                    } 
                } 
            }
           return deepElements; 
        }

        //find the depth of an DependencyObject
        public static uint GetTreeDepth(DependencyObject element) 
        {
            uint depth = 0; 
            while (element != null) 
            {
                depth++; 
                if (element is Visual || element is Visual3D)
                {
                    element = VisualTreeHelper.GetParent(element);
                } 
                else
                { 
                    element = LogicalTreeHelper.GetParent(element); 
                }
            } 
            return depth;
        }

        private class VisualState 
        {
            internal Visual Visual { get; set; } 
            internal uint Depth { get; set; } 

            internal VisualState(Visual visual, uint depth) 
            {
                this.Visual = visual;
                this.Depth = depth;
            } 
        }
    } 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK