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

时间:2009-12-29 01:08:57

标签: wpf data-binding accessibility datatemplate

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

这是我的数据模板:

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

1 个答案:

答案 0 :(得分:4)

您是否使用datatemplate作为商品容器类型控件的商品模板,例如一个ListBox?查看KeyboardNavigation课程,您可能需要为其项目容器设置其TabNavigation属性为“Continue”或“Cycle”,如下所示:

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

当使用ListBox中的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;
}