0

Upon click of a button I am trying to traverse the visual tree and list all the visible and focusable component controls (e.g. buttons, images, textBoxes etc) of the current window and set their TabIndex to some value. However several of the controls don't get listed or the tabIndexes don't get set!

Here is my class which adopted from here

 public class TabIndexer
{
    public IEnumerable<Control> FindVisualChildren(DependencyObject depObj)
    {
        if (depObj != null)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
                if (child != null && child is Control)
                {
                    yield return (Control)child;
                }

                foreach (var childOfChild in FindVisualChildren(child))
                {
                    yield return (Control)childOfChild;
                }
            }
        }
    }

    public T FindChild<T>(DependencyObject parent, string childName) where T : DependencyObject
    {
        // Confirm parent and childName are valid. 
        if (parent == null) return null;

        T foundChild = null;

        int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
        for (int i = 0; i < childrenCount; i++)
        {
            var child = VisualTreeHelper.GetChild(parent, i);
            // If the child is not of the request child type child
            T childType = child as T;
            if (childType == null)
            {
                // recursively drill down the tree
                foundChild = FindChild<T>(child, childName);

                // If the child is found, break so we do not overwrite the found child. 
                if (foundChild != null) break;
            }
            else if (!string.IsNullOrEmpty(childName))
            {
                var frameworkElement = child as FrameworkElement;
                // If the child's name is set for search
                if (frameworkElement != null && frameworkElement.Name == childName)
                {
                    // if the child's name is of the request name
                    foundChild = (T)child;
                    break;
                }
            }
            else
            {
                // child element found.
                foundChild = (T)child;
                break;
            }
        }

        return foundChild;
    }
}

and here is how it is called

private void Button_Click(object sender, RoutedEventArgs e)
    {
        var children = new TabIndexer().FindVisualChildren(this).Where(o => o.Focusable && o.Visibility == Visibility.Visible);

        int i = 0;
        foreach (var item in children)
        {
            item.TabIndex = i;
            ++i;
        }
        MessageBox.Show("no="+i);
    }
Community
  • 1
  • 1
Waterfr Villa
  • 1,217
  • 1
  • 10
  • 33
  • you can set this in the XAML which is probably more reliable than setting it programatically. – Simon Price Nov 02 '15 at 22:51
  • @SimonPrice The problem is that some of the controls are generated dynamically! – Waterfr Villa Nov 02 '15 at 22:54
  • The code that attempts to set the tab index is only half the equation. We also need to see the XAML and any other related code that creates the objects in the first place. Please provide [a good, _minimal_, _complete_ code example](http://stackoverflow.com/help/mcve) that reliably reproduces the problem. – Peter Duniho Nov 03 '15 at 04:48

0 Answers0