예제 #1
0
        // Helper method that performs a recursive, depth-first search of children starting at the specified parent,
        // looking for any children that conform to the specified Type and are marked with a SelectionStop
        //
        private static T FindChildSelectionStop <T>(DependencyObject parent, int leftIndex, int rightIndex, SearchDirection iterationDirection, int maxDepth, MatchDirection matchDirection)
            where T : DependencyObject
        {
            if (parent == null || maxDepth <= 0)
            {
                return(null);
            }

            int step  = iterationDirection == SearchDirection.Next ? 1 : -1;
            int index = iterationDirection == SearchDirection.Next ? leftIndex : rightIndex;

            for (; index >= leftIndex && index <= rightIndex; index = index + step)
            {
                DependencyObject child = VisualTreeHelper.GetChild(parent, index);

                // If MatchDirection is set to Down, do an eligibility match BEFORE we dive down into
                // more children.
                //
                if (matchDirection == MatchDirection.Down && IsEligibleSelectionStop <T>(child))
                {
                    return((T)child);
                }

                // If this child is not an eligible SelectionStop because it is not visible,
                // there is no point digging down to get to more children.
                //
                if (!VisualTreeUtils.IsVisible(child as UIElement))
                {
                    continue;
                }

                int grandChildrenCount = VisualTreeHelper.GetChildrenCount(child);
                if (grandChildrenCount > 0 && IsExpanded(child))
                {
                    T element = FindChildSelectionStop <T>(child, 0, grandChildrenCount - 1, iterationDirection, maxDepth - 1, matchDirection);

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

                // If MatchDirection is set to Up, do an eligibility match AFTER we tried diving into
                // more children and failed to find something we could return.
                //
                if (matchDirection == MatchDirection.Up && IsEligibleSelectionStop <T>(child))
                {
                    return((T)child);
                }
            }

            return(null);
        }
예제 #2
0
        // Helper method used from GetNeighborSelectionStop()
        // Returns a parent DependencyObject of the specified element that is
        //
        //  * Visible AND
        //  * ( Marked with a SelectionStop OR
        //  *   Marked with IsSelectionScope = true OR
        //  *   Has more than one child )
        //
        private static DependencyObject GetEligibleParent(DependencyObject element, out int childIndex, out int childrenCount, out int childDepth, out bool isSelectionStop, out bool isSelectionScope)
        {
            childDepth       = 0;
            isSelectionStop  = false;
            isSelectionScope = false;
            bool isVisible;

            do
            {
                element          = VisualTreeUtils.GetIndexedVisualParent(element, out childrenCount, out childIndex);
                isSelectionStop  = element == null ? false : (GetSelectionStop(element) != null);
                isSelectionScope = element == null ? false : GetIsSelectionScope(element);
                isVisible        = VisualTreeUtils.IsVisible(element as UIElement);

                childDepth++;
            }while (
                element != null &&
                (isVisible == false ||
                 (isSelectionStop == false &&
                  isSelectionScope == false &&
                  childrenCount < 2)));

            return(element);
        }
예제 #3
0
 // Helper method that return true if the given element is marked with a SelectionStop,
 // if it derives from the specified Type, and if it is Visible (assuming it derives from UIElement)
 //
 private static bool IsEligibleSelectionStop <T>(DependencyObject element) where T : DependencyObject
 {
     return((GetSelectionStop(element) != null) && typeof(T).IsAssignableFrom(element.GetType()) && VisualTreeUtils.IsVisible(element as UIElement));
 }