wondra
wondra

Reputation: 3573

WPF TabControl cannot switch tabs when hosting DataGrid

In the default TabControl you can switch tabs using Ctrl+Tab, however if one of the tabs contain DataGrid it all breaks. For example, if I had a simple TabControl containing nothing but TextBoxes:

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

And repeatedly pressed Ctrl+Tab, current Tab would cycle:

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

but if I were to put virtually any DataGrid in one of the middle Tabs, for example:

...    
<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>

the Ctrl+Tab would get stuck not being able to ever get past said Tab:

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

How can I fix the issue?


I have tried IsTabStop="False" on the DataGrid and several combinations of KeyBoardNavigation properties, all of those had either no effect or were contraproductive.


Edit(2): the issue seems to appear mainly when the DataGrid is the first focusable child of TabItem, for example content:

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

almost works, until user selects the DataGrid. If the grid is selected next Ctrl+Tab goes back to first Tab rather than to the next one.

Upvotes: 0

Views: 608

Answers (2)

DRapp
DRapp

Reputation: 48139

Have you tried

IsTabStop="False"

on your controls. This prevents focus into that control? A user could still manually click on the grid for focus (or other control), but without, it will ignore trying to get focus to that control.

Just to expand on the IsTabStop, you may want to try wrapping it into a user control and stop at the user control so it does not go into anything WITHIN it... such as

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

Upvotes: 0

SamTh3D3v
SamTh3D3v

Reputation: 9944

Looks like it's a focus problem, when the Datagrid gets the focus it's lost from the TabControl, so set that focus programmatically whenever the ctrl/tab is pressed where the DataGrid is:

 <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>

The handler:

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

Upvotes: 1

Related Questions