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): 问题似乎主要出现在 DataGrid
是 first 可聚焦子项时 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();
}
}
在默认 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): 问题似乎主要出现在 DataGrid
是 first 可聚焦子项时 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();
}
}