views:

334

answers:

1

I'm writing a really simple name / value editor control where the value is editable - label on left and property text box on right. Control works fine except that when the user hits TAB when inside one of the "value" text boxes on the right, the focus shifts away from my control to the next control in the hiearchy. I want the focus to go to the next text box in my control so users can just tab between property text boxes. I tried setting "IsTabStop" to true but doesn't seem to work.

Here's my data template:

    <DataTemplate x:Key="myDataTemplate">
        <StackPanel>
            <TextBlock Text="{Binding Name}" />
            <TextBox IsTabStop="True" Text="{Binding Value, Mode=TwoWay}" />
        </StackPanel>
    </DataTemplate>
+1  A: 

Are you using your datatemplate as an item template for the items container type control, e.g. a ListBox? Check out a KeyboardNavigation class, you might want to setup its TabNavigation property to "Continue" or "Cycle" for your items container, smth like this:

<ListBox x:Name="myListBox"
    KeyboardNavigation.TabNavigation="Continue"
    ItemTemplate="{StaticResource myDataTemplate}" 
...

when focus is changed using the tab key within the ListBox, focus will move from each element and when the last element is reached focus will return to the first element for "Cycle" or move to next focusable control on the form if "Continue" is set up.

hope this helps, regards

edit0: make text box receive focus right after listbox item gets selected

<ListBox x:Name="myListBox"
    KeyboardNavigation.TabNavigation="Continue"
    ItemTemplate="{StaticResource myDataTemplate}" 
    SelectionChanged="testList_SelectionChanged"
...
/>
private void testList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    Dispatcher.BeginInvoke(DispatcherPriority.Normal, new ThreadStart(() =>
    {
        ListBoxItem item = testList.ItemContainerGenerator.ContainerFromIndex(testList.SelectedIndex) as ListBoxItem;
        if (item != null)
        {
            TextBox textBox = GetDescendantTextBox(item) as TextBox;
            if (textBox != null) textBox.Focus();
        }
    }));
}

public static Visual GetDescendantTextBox(Visual element)
{
    if (element == null) return null;
    if (element is TextBox) return element;
    Visual result = null;
    if (element is FrameworkElement)
        (element as FrameworkElement).ApplyTemplate();
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++)
    {
        Visual visual = VisualTreeHelper.GetChild(element, i) as Visual;
        result = GetDescendantTextBox(visual);
        if (result != null) break;
    }
    return result;
}
serge_gubenko
This helped, thanks! But now I'm seeing a tab stop around the textbox and what looks like the itemcontainer. I only wanted the TextBox to have focus, any ideas?
will
the idea would be to pass focus to the edit box whenever listboxitem gets selected. I've edited my original post with SelectionChanged event handler of the listbox. See if it works for you, regards
serge_gubenko
Worked a treat, thank you so much Serge...
will