tags:

views:

560

answers:

2

I have a requirement to be able to auto-tab from one control to the "next control" in a SL3 app. For example, a TextBox is limited to 3 characters - on typing the 3rd character the focus should automatically move to the next control on the form (my actual usage is slightly different but that example suffices).

However, as SL automatically determines the tab sequence there doesn't seem to be a way of doing this apart from reverse engineering/duplicating Silverlight's logic to figure out which control in the visual tree should be the next control to gain focus.

Has anybody implemented this already?

+2  A: 

If you're looking for a generalized solution, and are OK basing it on the visual tree ordering (as opposed to arranged layout), I imagine it would not be so bad. Haven't heard of it being done, though.

Most of the phone number or credit card entry forms I've seen with this behavior honestly just hard-code the next field in the proper change handler when the right # of characters have been entered.

Since it sounds like your auto-focusing solution (for 3 chars) is going to already require some sort of event hookup, monitoring the TextChanged event, couldn't you just go ahead and either 1) hard-code a Focus() to the next form element that you know, 2) use the Tag property to store the name of the control that you'd like to focus next, then do a FindName + Focus on that, or 3) do some sort of VisualTreeHelper (or logical tree search through peers)?

Jeff Wilcox
+2  A: 

I was looking for a fairly generalised solution - but I've been able to make do with something fairly specific - basically it uses the VisualTreeHelper to find children with the same parent as the control that I want to tab next to, and sets focus to that.

It's a more palatable solution than having to go through all my controls (and this is for a fairly large LOB application) and configure the "next" control for each of them.

Here's my code, in case it helps somebody else. (VisualTreeeHelperUtil is a class of my own that adds some utility functions to VisualTreeHelper)

public static void TabNext(DependencyObject parentElement, Control fromControl)
{
    var children = VisualTreeHelperUtil.FindChildren<Control>(parentElement).
        Where(c => c.IsEnabled && c.IsTabStop && c.Visibility == Visibility.Visible).
        ToList();

    if (children.Contains(fromControl))
    {
        var thisIndex = children.IndexOf(fromControl);
        var targetIndex = thisIndex + 1;
        if (children.Count > targetIndex)
        {
            var targetChild = children[targetIndex];
            fromControl.Dispatcher.BeginInvoke(() =>
               {
                   targetChild.Focus();
                   var txt = targetChild as TextBox;
                   if (txt != null)
                   {
                       txt.SelectAll();
                   }
               });
        }
    }
}
Craig Shearer