制表位不适用于数据模板内的文本框

wil*_*ill 3 data-binding wpf accessibility datatemplate

我正在编写一个非常简单的名称/值编辑器控件,其中值是可编辑的 - 左侧的标签和右侧的属性文本框。控件工作正常,只是当用户在右侧的“值”文本框之一内按 TAB 时,焦点将从我的控件转移到层次结构中的下一个控件。我希望焦点转到控件中的下一个文本框,以便用户可以在属性文本框之间进行切换。我尝试将“IsTabStop”设置为 true 但似乎不起作用。

这是我的数据模板:

    <DataTemplate x:Key="myDataTemplate">
        <StackPanel>
            <TextBlock Text="{Binding Name}" />
            <TextBox IsTabStop="True" Text="{Binding Value, Mode=TwoWay}" />
        </StackPanel>
    </DataTemplate>
Run Code Online (Sandbox Code Playgroud)

ser*_*nko 5

您是否使用数据模板作为项目容器类型控件(例如列表框)的项目模板?查看KeyboardNavigation类,您可能希望将其 TabNavigation 属性设置为项目容器的“继续”或“循环”,如下所示:

<ListBox x:Name="myListBox"
    KeyboardNavigation.TabNavigation="Continue"
    ItemTemplate="{StaticResource myDataTemplate}" 
...
Run Code Online (Sandbox Code Playgroud)

当使用列表框中的 Tab 键更改焦点时,焦点将从每个元素移动,当到达最后一个元素时,焦点将返回到“循环”的第一个元素,或者如果选择“继续”,则移动到表单上的下一个可聚焦控件设置。

希望这有帮助,问候

edit0:使文本框在选择列表框项目后立即获得焦点

<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;
}
Run Code Online (Sandbox Code Playgroud)