0
votes

I have a page with a DataGrid, and several buttons. I have the SelectionUnit of the DataGrid set up for FullRow.

        <Button Grid.Row="0" Height="20" Width="50" Content="Config" FontSize="11"               
                Background="{StaticResource DefButtonBackgroundBrush}"/>

        <DataGrid Grid.Row="1"
                  AutoGenerateColumns="False"
                  IsReadOnly="True"
                  SelectionMode="Single"
                  SelectionUnit="FullRow"
                  GridLinesVisibility="None"
                  Name="MatipBatapConfigList"               
                  ColumnHeaderStyle="{StaticResource DGHdr_2LineNormal}"
                  ItemsSource="{Binding}">
            ...........................
        </DataGrid>

        <Button Grid.Row="2" Height="20" Width="50" Content="Edit" FontSize="11"               
                Background="{StaticResource DefButtonBackgroundBrush}"/>

        <Button Grid.Row="3" Height="20" Width="50" Content="Add" FontSize="11"               
                Background="{StaticResource DefButtonBackgroundBrush}"/>

        <Button Grid.Row="4" Height="20" Width="50" Content="Delete" FontSize="11"               
                Background="{StaticResource DefButtonBackgroundBrush}"/>

If I start tabbing, the order of focus is

  • Config button
  • Column 0 header of DataGrid
  • Column 1 header of DataGrid
    ....
  • Last Column header of DataGrid
  • Cell at Row 0, Column 0 of DataGrid
  • Cell at Row 0, Column 1 of DataGrid
    ....
  • Cell at Row 0, last Column of DataGrid
    ....
  • Cell at last Row, last Column of DataGrid
  • Edit button
  • Add button
  • Delete button
  • back to top

The order I want is:

  • Config button
  • DataGrid (one stop here, no focus per se, but use arrow buttons to selecte rows)
  • Edit button
  • Add button
  • Delete button
  • back to top

So, tab only takes you into and out-of the DataGrid, but no more. Arrow/Page buttons are used to move within the DataGrid.

I've tried many things over the past 2 days, including setting IsTabStop to False on header style, cell style, and playing around with KeyboardNavigationMode.TabNavigation

Any ideas?

================== Edit: expansion upon mm8 's answer ==================

I wound up using mm8's answer. Here is my expanded solution based on that answer. Tab now just takes you into/outof the DataGrid, arrows move line-to-line within the DataGrid.

xaml:

        <Button Grid.Row="0" Height="20" Width="50" Content="Config" FontSize="11"               
                x:Name="ConfigButton"
                Background="{StaticResource DefButtonBackgroundBrush}"/>

        <DataGrid Grid.Row="1"
                  AutoGenerateColumns="False"
                  IsReadOnly="True"
                  SelectionMode="Single"
                  SelectionUnit="FullRow"
                  GridLinesVisibility="None"
                  Name="MatipBatapConfigList"               
                  PreviewKeyDown="DataGrid_PreviewKeyDown"
                  GotFocus="MatBatConfigList_GotFocus"
                  KeyboardNavigation.TabNavigation ="Once"
                  ColumnHeaderStyle="{StaticResource DGHdr_2LineNormal}">
            ...........................
        </DataGrid>

        <Button Grid.Row="2" Height="20" Width="50" Content="Edit" FontSize="11"               
                x:Name="EditButton"
                Background="{StaticResource DefButtonBackgroundBrush}"/>

        <Button Grid.Row="3" Height="20" Width="50" Content="Add" FontSize="11"               
                Background="{StaticResource DefButtonBackgroundBrush}"/>

        <Button Grid.Row="4" Height="20" Width="50" Content="Delete" FontSize="11"               
                Background="{StaticResource DefButtonBackgroundBrush}"/>

Code-behind:

        private void DataGrid_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            DataGrid dg = (DataGrid)MatipBatapConfigList;
            int count = dg.Items.Count;

            if ((dg.SelectedIndex < 0) && (count > 0)) dg.SelectedIndex = 0;

            switch (e.Key)
            {
                case Key.Tab:
                    if ((Keyboard.Modifiers & (ModifierKeys.Shift)) == ModifierKeys.Shift)
                    {
                        e.Handled = true;
                        ConfigButton.Focus();
                    }
                    else
                    {
                        e.Handled = true;
                        EditButton.Focus();
                    }
                    break;

                case Key.Down:
                    if (count > 0)
                    {
                        if (dg.SelectedIndex == (count - 1))
                        {
                            dg.SelectedIndex = 0;
                        }
                        else
                        {
                            dg.SelectedIndex++;
                        }
                        dg.CurrentItem  = dg.Items[dg.SelectedIndex];
                        dg.SelectedItem = dg.Items[dg.SelectedIndex];
                        dg.UpdateLayout();
                        dg.ScrollIntoView(dg.SelectedItem);
                    }
                    e.Handled = true;
                    break;

                case Key.Up:
                    if (count > 0)
                    {
                        if (dg.SelectedIndex == 0)
                        {
                            dg.SelectedIndex = count - 1;
                        }
                        else
                        {
                            dg.SelectedIndex--;
                        }
                        dg.CurrentItem  = dg.Items[dg.SelectedIndex];
                        dg.SelectedItem = dg.Items[dg.SelectedIndex];
                        dg.UpdateLayout();
                        dg.ScrollIntoView(dg.SelectedItem);
                    }
                    e.Handled = true;
                    break;
            }

        }


        private void MatBatConfigList_GotFocus(object sender, RoutedEventArgs e)
        {
            DataGrid dg = (DataGrid)MatipBatapConfigList;
            int count = dg.Items.Count;

            if ((dg.SelectedIndex < 0) && (count > 0))
            {
                dg.SelectedIndex = 0;
                dg.CurrentItem   = dg.Items[dg.SelectedIndex];
                dg.SelectedItem  = dg.Items[dg.SelectedIndex];
                if (dg.CurrentColumn == null) dg.CurrentColumn = dg.ColumnFromDisplayIndex(1);
                dg.ScrollIntoView(dg.SelectedItem);
            }
        }
1

1 Answers

0
votes

The easiest way to handle this is probably to give the edit button an x:Name in the XAML markup and focus it programmtically by handling the PreviewKeyDown event for the DataGrid:

private void DataGrid_PreviewKeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Tab)
    {
        e.Handled = true;
        edit.Focus();
    }
}

XAML:

<Button x:Name="edit" Grid.Row="2" Height="20" Width="50" Content="Edit" FontSize="11"               
        Background="{StaticResource DefButtonBackgroundBrush}"/>

If you define custom elements in the headers, you should set the IsTabStop property of these to false.