Posts Tagged Visual Tree

Finding a typed visual parent in Silverlight


My application frequently needs to find a parent of a Silverlight element, and due to the nature of popup panels I also sometimes want to know if the element is “logically” connected to another element.  To achieve this I wrote a couple of helper functions that walk the visual tree and return a typed parent.  You can implement a special interface to indicate that there is a logical connection between items that aren’t physically connected to each other in the Visual Tree too if you need to (very helpful with focus issues).


        public static T FirstVisualAncestorOfType<T>(this DependencyObject element) where T : DependencyObject
        {
            if (element == null) return null;
           
            var parent = VisualTreeHelper.GetParent(element) as DependencyObject;
            while (parent != null)
            {
                if (parent is T)
                    return (T)parent;
                if (parent is IBreakVisualParenting)
                {
                    parent = ((IBreakVisualParenting)parent).Parent;
                }
                else
                    parent = VisualTreeHelper.GetParent(parent) as DependencyObject;
            }
            return null;
        }

        public interface IBreakVisualParenting
        {
            DependencyObject Parent { get; }
        }

        public static T LastVisualAncestorOfType<T>(this DependencyObject element) where T : DependencyObject
        {
            T item = null;
            var parent = VisualTreeHelper.GetParent(element) as DependencyObject;
            while (parent != null)
            {
                if (parent is T)
                    item = (T) parent;
                if(parent is IBreakVisualParenting)
                {
                    parent = ((IBreakVisualParenting) parent).Parent;
                }
                else
                    parent = VisualTreeHelper.GetParent(parent) as DependencyObject;
            }
            return item;
        }

, ,

Leave a comment

IsInVisualTree – helper function for determining if a Silverlight item is visible or in the visual tree


Some Silverlight functions, especially those to do with coordinate transforms, tend to throw exceptions if the item you are testing isn’t in the visual tree and it is often interesting to know if an item is presently going to be displayed or not.  The following code uses the standard way of determining this, by walking the visual tree to see if the item is connected to the root visual of the application.  Being in the visual tree doesn’t mean the item is actually visible, this depends on the collapsed state of the element and its parents.


        /// <summary>
        /// Determines if an element is in the visual tree
        /// </summary>
        /// <param name="element">The element.</param>
        /// <returns>
        ///  <c>true</c> if element parameter is in
        ///  visual tree otherwise, <c>false</c>.
        /// </returns>
        public static bool IsInVisualTree(this DependencyObject element)
        {
            return IsInVisualTree(element, Application.Current.RootVisual as DependencyObject);
        }

        public static bool IsInVisualTree(this DependencyObject element, DependencyObject ancestor)
        {
            DependencyObject fe = element;
            while (fe != null)
            {
                if (fe == ancestor)
                {
                    return true;
                }

                fe = VisualTreeHelper.GetParent(fe) as DependencyObject;
            }

            return false;
        }

To test if an item is visible you just walk the parents and check the Visibility state:


        public static bool IsVisible(this FrameworkElement ele, FrameworkElement topParent=null)
        {
            if (!ele.IsInVisualTree()) return false;

            while(ele != topParent && ele != null)
            {
                if (ele.Visibility == Visibility.Collapsed) return false;
               ele = VisualTreeHelper.GetParent(ele) as FrameworkElement;
            }
            return true;
        }

, , , , ,

Leave a comment