Search code examples
c#xamlwinui-3winuiwindows-community-toolkit

In WinUI 3 DataGrid tab key not working properly


When i was single click on particular column and press tab key then it will focus on column header not next column. How i will resolved it. Ref:-

<controls:DataGrid x:Name="grid" CanUserSortColumns="True" SelectionMode="Extended"
                    Height="326" Width="1660" HorizontalAlignment="Center" VerticalAlignment="Top" HorizontalContentAlignment="Center" 
                    AutoGenerateColumns="False" BorderBrush="Black" BorderThickness="1" FontSize="10" GridLinesVisibility="All"
                    ColumnHeaderHeight="25" RowBackground="White" TabFocusNavigation="Cycle" TabNavigation="Cycle"
                    VerticalScrollBarVisibility="Auto">
<controls:DataGrid.Columns>
<controls:DataGridTextColumn Width="20" Binding="{Binding Id, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontSize="10"/>
<controls:DataGridTemplateColumn Header="PG" Tag="PG" Width="44">
    <controls:DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBox IsReadOnly="True" Text="{Binding RPe,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="45" MinHeight="28" HorizontalAlignment="Left" 
                     Margin="8 -4 0 0" Padding="20 5 0 0" FontSize="10" Background="Transparent" BorderThickness="0" CornerRadius="0" />
        </DataTemplate>
    </controls:DataGridTemplateColumn.CellTemplate>
</controls:DataGridTemplateColumn>
<controls:DataGridTemplateColumn Header="P" Width="174" CanUserSort="True" Tag="Part" >
    <controls:DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal" Margin="10,0,0,15">
                <TextBlock x:Name="pnum" Text="{Binding Pnum, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontSize="10" 
                         VerticalAlignment="Center" Foreground="Black">
                </TextBlock>
            </StackPanel>
        </DataTemplate>
    </controls:DataGridTemplateColumn.CellTemplate>
</controls:DataGridTemplateColumn>

Solution

  • You can capture the PreviewKeyDown event and apply your custom behavior.

    <controls:DataGrid PreviewKeyDown="DataGrid_PreviewKeyDown" ... />
    
    private void DataGrid_PreviewKeyDown(object sender, KeyRoutedEventArgs e)
    {
        if (e.Key is not VirtualKey.Tab ||
            sender is not DataGrid dataGrid)
        {
            return;
        }
    
        int nextColumnIndex = dataGrid.Columns.IndexOf(dataGrid.CurrentColumn);
        nextColumnIndex += 1;
    
        if (nextColumnIndex >= dataGrid.Columns.Count)
        {
            nextColumnIndex = 0;
            
            // Should be faster if you can get the count directly from the source.
            int itemsCount = dataGrid.ItemsSource.Cast<object>().Count();
    
            int nextRowIndex = dataGrid.SelectedIndex + 1;
            dataGrid.SelectedIndex = nextRowIndex < itemsCount
                ? nextRowIndex
                : 0;
        }
    
        if (dataGrid.Columns.ElementAtOrDefault(nextColumnIndex) is not { } column)
        {
            return;
        }
    
        dataGrid.CurrentColumn = column;
        e.Handled = true;
    }