5

I have a Window with few controls on it. One of them is a DataGrid. I want to implement some non-default focus traversal. Namely:

  • DataGrid is a single stop as a whole, not each row.
  • When DataGrid is focused, user can navigate through rows using up and down keys.
  • Navigating through columns using left and right keys is not allowed.
  • First column (and the only relevant for navigation) is of type DataGridHyperlinkColumn. When user hits Space or Enter key, it executes the hyperlink.

At the moment I have the following code:

<DataGrid x:Name="DocumentTemplatesGrid"
          Grid.Row="2"
          ItemsSource="{Binding Source={StaticResource DocumentTemplatesView}}"
          IsReadOnly="True"
          AutoGenerateColumns="False"
          SelectionUnit="FullRow"
          SelectionMode="Single"
          TabIndex="1"
          IsTabStop="True">
  <DataGrid.CellStyle>
    <Style TargetType="DataGridCell">
      <Setter Property="IsTabStop" Value="False"/>
    </Style>
  </DataGrid.CellStyle>
  <DataGrid.RowStyle>
    <Style TargetType="DataGridRow">
      <Setter Property="IsTabStop" Value="False"/>
    </Style>
  </DataGrid.RowStyle>
  <DataGrid.Columns>
    <DataGridHyperlinkColumn Header="Name"
                             Width="2*"
                             Binding="{Binding Name}"/>
    <DataGridTextColumn Header="Description"
                        Width="5*"
                        Binding="{Binding Description}"/>
    <DataGridTextColumn Header="Type"
                        Width="*"
                        Binding="{Binding Type}"/>
  </DataGrid.Columns>
</DataGrid>

Unfortunately, it does not reach my expectations. Could you, please, explain how to achieve this?

Massimiliano Kraus
  • 3,638
  • 5
  • 27
  • 47
Dawid
  • 763
  • 1
  • 8
  • 17
  • Which of 4 features do you need assistance? TabStops (1) and Up-Down navigation (2) worked as expected when I tried you code – ASh Nov 02 '16 at 07:14
  • There are multiple issues with it. DataGrid is a single stop as a whole, but the problem is that when I traverse to the control that has the largest number in TabIndex property and TAB once again, it traverse to the rows of the data grid and using TAB few more times keeps traversing it row by row. That is not acceptable. Navigating through rows should be done only by arrow keys. Moreover, during the first correct visit to the data grid, when i use arrow key it does not select any of the rows. It goes to the next or previous control. So the first and the second feature don't work properly. – Dawid Nov 03 '16 at 12:17

1 Answers1

3

So, my suggestion to you is this:

 <DataGrid x:Name="DocumentTemplatesGrid"
              Grid.Row="2"
              ItemsSource="{Binding Items}"
              IsReadOnly="True"
              AutoGenerateColumns="False"
              SelectionMode="Single"
              SelectionUnit="FullRow"
              TabIndex="1"
              IsTabStop="True"
              PreviewKeyDown="DocumentTemplatesGrid_PreviewKeyDown">
        <DataGrid.CellStyle>
            <Style TargetType="DataGridCell">
                <Setter Property="IsTabStop" Value="False"/>
                <Setter Property="BorderThickness" Value="0"/>
                <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
            </Style>
        </DataGrid.CellStyle>
        <DataGrid.RowStyle>
            <Style TargetType="DataGridRow">
                <Setter Property="IsTabStop" Value="False"/>
            </Style>
        </DataGrid.RowStyle>

I have added the PreviewKeyDown event on the DataGrid, and I have removed the cell selection from each cell. As a result, it will seem like selection is on row only.

In the code behind, this is what opens the links with Space / Enter:

private void DocumentTemplatesGrid_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
    {
        if (e.Key == System.Windows.Input.Key.Space || e.Key == System.Windows.Input.Key.Enter)
        {
            if (e.Source is DataGrid)
            {
                string navigationUri = ((e.Source as DataGrid).SelectedItem as Class).Name;
                Process.Start(navigationUri);
            }
            e.Handled = true;
        }
    }

Hope this is what you are looking for, or atleast of some help.

Lupu Silviu
  • 1,145
  • 11
  • 23