WPF TabControl 在托管 DataGrid 时无法切换选项卡

WPF TabControl cannot switch tabs when hosting DataGrid

在默认 TabControl 中,您可以使用 Ctrl+Tab 切换选项卡,但是如果其中一个选项卡包含 DataGrid 都坏了。例如,如果我有一个简单的 TabControl 只包含文本框:

<TabControl>
    <TabItem Header="Tab1">
        <TextBox/>
    </TabItem>
    <TabItem Header="Tab2">
        <TextBox/>
    </TabItem>
    <TabItem Header="Tab3">
        <TextBox/>
    </TabItem>
</TabControl>

并反复按Ctrl+Tab,当前Tab会循环:

Tab1 > Tab2 > Tab3 > Tab1 > ...etc

但是如果我将几乎任何 DataGrid 放在中间的选项卡之一中,例如:

...    
<TabItem Header="Tab2"> <!--replacing 2nd tab content-->
    <TabItem.Resources>
        <x:Array x:Key="Items" Type="{x:Type Run}">
            <Run Text="Foo"/>
            <Run Text="Bar"/>
            <Run Text="Baz"/>
        </x:Array>
    </TabItem.Resources>
    <DataGrid ItemsSource="{StaticResource Items}"/>
</TabItem>

Ctrl+Tab 会卡住无法通过 Tab:

Tab1 > Tab2 > Tab1 > Tab2 > ...etc

我该如何解决这个问题?


我已经在 DataGrid 上尝试了 IsTabStop="False"KeyBoardNavigation 属性的几种组合,所有这些要么没有效果,要么适得其反。


Edit(2): 问题似乎主要出现在 DataGridfirst 可聚焦子项时 TabItem,例如内容:

<StackPanel>
    <TextBox/>
    <DataGrid ItemsSource="{StaticResource Items}"/>
</StackPanel>

几乎 有效,直到用户选择 DataGrid。如果接下来选择网格 Ctrl+Tab 返回第一个 Tab 而不是下一个。

你试过了吗

IsTabStop="False"

在您的控件上。这会阻止焦点进入该控件?用户仍然可以手动单击网格以获得焦点(或其他控件),但如果没有,它将忽略尝试将焦点放在该控件上。

只是为了扩展 IsTabStop,您可能想尝试将其包装到用户控件中并在用户控件处停止,这样它就不会进入其中的任何内容...例如

<UserControl IsTabStop="false">
   <DataGrid>
      …
   </DataGrid>
</UserControl>

看起来这是一个焦点问题,当 Datagrid 获得焦点时它从 TabControl 丢失了焦点,因此每当 ctrl/tab 在 [=] 处按下时以编程方式设置焦点14=] 是:

 <TabControl  x:Name="TabCtrl">
        <TabItem Header="Tab1" x:Name="Tab1" >
            <TextBox/>
        </TabItem>
        <TabItem Header="Tab3" x:Name="Tab2"  PreviewKeyDown="UIElement_OnPreviewKeyDown">
            <TabItem.Resources>
                <x:Array x:Key="Items" Type="{x:Type Run}">
                    <Run Text="Foo"/>
                    <Run Text="Bar"/>
                    <Run Text="Baz"/>
                </x:Array>
            </TabItem.Resources>
            <DataGrid ItemsSource="{StaticResource Items}" />
        </TabItem>
        <TabItem Header="Tab2"  x:Name="Tab3">
            <TextBox/>
        </TabItem>
    </TabControl>

处理人:

 private void UIElement_OnPreviewKeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Tab &&
            (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control && sender is TabItem)
        {
            TabCtrl.Focus();
        }
    }