In wpf, how can I get the next control in the tab order
Asked Answered
R

3

8

I know how to set the focus to the next control in the tab order, but I don't actually want to change focus... I just want to get the next control in the tab order (perhaps get the previous, first and last ones too.) So... howyadodat?

M

Reedreedbird answered 22/4, 2011 at 14:26 Comment(2)
By the way, how do you set the focus to the next UIElement?Torose
Idea: to write a traversal algorithm that adds UIElements to the list in the Tab order (once). Then look up the control in the list and see who's next.Torose
A
1

PredictFocus(FocusNavigationDirection.Next) doesn't work as @Cameron said. My wrapper code based on @Randolpho 's post is now working well.

I tried several patterns and finally concluded I have to make sure container is actually one of the parents of e to avoid unexpected results.

/// <summary>
/// Get next tab order element.
/// </summary>
/// <param name="e">The element to get next tab order</param>
/// <param name="container">The container element owning 'e'. Make sure this is a container of 'e'.</param>
/// <param name="goDownOnly">True if search only itself and inside of 'container'; otherwise false.
/// If true and next tab order element is outside of 'container', result in null.</param>
/// <returns>Next tab order element or null if not found</returns>
public DependencyObject GetNextTab(DependencyObject e, DependencyObject container, bool goDownOnly)
{
    var navigation = typeof(FrameworkElement)
        .GetProperty("KeyboardNavigation", BindingFlags.NonPublic | BindingFlags.Static)
        .GetValue(null);

    var method = navigation
        .GetType()
        .GetMethod("GetNextTab", BindingFlags.NonPublic | BindingFlags.Instance);

    return method.Invoke(navigation, new object[] { e, container, goDownOnly }) as DependencyObject;
}

Ex.)

var nextElement = GetNextTab(textbox1, window, false);
Alsworth answered 21/10, 2016 at 7:30 Comment(0)
S
0

I don't think is possible to have the next control in tab order, but you can loop on the children collection and use the KeyboardNavigation.GetIsTabStop(..) KeyboardNavigation.GetTabIndex() to create an helper for thet.

Scotty answered 22/4, 2011 at 14:42 Comment(0)
C
0

PredictFocus was supposed to get Tab support in .NET 4, but the current MSDN implies it hasn't. That may be a documentation oversight, however; I haven't tried it, but you could give it a shot.

If that doesn't work, there's a private method on KeyboardNavigation that may do you some good; you'll have to use reflection to call it, and you'll need the proper code access permissions to do it, but it might work. .NET Reflector reveals the signature as follows:

private DependencyObject GetNextTab(DependencyObject e, DependencyObject container, bool goDownOnly)

Where e is the element for which you want to get the next tab, and container is its parent container. I'm not 100% sure what goDownOnly does, but I guess that it indicates that you don't want to leave the parent container. The method will return null if there isn't a next tab for that element.

Keep in mind, this is a private method; highly susceptible to change come the next version.

Edit: you'll need an instance of KeyboardNavigation! Totally forgot about that. There's a static one at FrameworkElement.KeyboardNavigation, but it's also internal, so reflection to get at it.

Collyrium answered 22/4, 2011 at 15:11 Comment(1)
The documentation isn't an oversight -- it still throws an InvalidEnumArgumentException in .NET 4Ruse

© 2022 - 2024 — McMap. All rights reserved.