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 char
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();
}
});
}
}
}
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)?