15

我有一个带有多列的 WPF 工具包数据网格。我试图获得一种行为,您可以使用选项卡进入网格,然后使用单个选项卡再次进行选项卡。例如,我不想在网格的所有列或单元格中进行制表符,只需一次进入,一次退出。

有没有简单的解决方案,我尝试将 TabNavigation 设置为 Once,同时禁用 TabStop(未在下面的代码中显示)并将列上的 TabNavigation 设置为 None,但没有成功。

有什么我遗漏的或者我需要处理代码中的 Tab 键吗?

        <my:DataGrid Name="datagrid"
                     AutoGenerateColumns="False" IsReadOnly="True"
                     CanUserAddRows="False" CanUserDeleteRows="False"
                     Background="White"
                     KeyboardNavigation.TabNavigation="Once">
            <my:DataGrid.Columns>
                <my:DataGridTextColumn x:Name="ID" Header="ID" Width="1*" ></my:DataGridTextColumn>
                <my:DataGridTextColumn x:Name="Ticker" Header="Ticker" Width="1*" KeyboardNavigation.TabNavigation="None"></my:DataGridTextColumn>
                <my:DataGridTextColumn x:Name="OfficialName" Header="Name" Width="3*" KeyboardNavigation.TabNavigation="None"></my:DataGridTextColumn>
            </my:DataGrid.Columns>
        </my:DataGrid>
4

3 回答 3

21

有趣的是,直接在 DataGridTextColumn 上设置 KeyboardNavigation 不起作用。应该可行的替代方法是设置 DataGridCell 样式。

<toolkit:DataGrid.CellStyle>
    <Style TargetType="{x:Type toolkit:DataGridCell}">
        <Setter Property="KeyboardNavigation.IsTabStop"
                Value="False" />
        <Style.Triggers>
            <Trigger Property="IsSelected"
                     Value="True">
                <Setter Property="KeyboardNavigation.IsTabStop"
                        Value="True" />
            </Trigger>
        </Style.Triggers>
    </Style>
</toolkit:DataGrid.CellStyle>

将此附加到 DataGrid 将确保一个单元格只是一个 TabStop(如果它已被选中)。但是,如果您选择整行并且没有在 DataGrid 上设置 SelectionUnit="Cell",它仍将循环遍历当前选定行的每一列。

相反,我们可以在 DataGrid 中创建多个 CellStyles 作为资源:

<toolkit:DataGrid.Resources>

    <Style  x:Key="SelectableCellStyle"
            TargetType="{x:Type toolkit:DataGridCell}">
        <Setter Property="KeyboardNavigation.IsTabStop"
                Value="False" />
        <Style.Triggers>
            <Trigger Property="IsSelected"
                     Value="True">
                <Setter Property="KeyboardNavigation.IsTabStop"
                        Value="True" />
            </Trigger>
        </Style.Triggers>
    </Style>

    <Style TargetType="{x:Type toolkit:DataGridCell}">
        <Setter Property="KeyboardNavigation.IsTabStop"
                Value="False" />
    </Style>

</toolkit:DataGrid.Resources>

现在我们有一个样式默认应用于所有 DataGridCells 并关闭 TabStop,以及一个键控样式,允许在选择单元格(或整行)时进行选择。将此样式仅应用于单个列将为我们提供相同的单选项卡效果,同时允许选择整行及其所有列。

 <my:DataGridTextColumn x:Name="ID" Header="ID" Width="1*" CellStyle={StaticResource  SelectableCellStyle}"/>

如果未选择任何内容,这也会停止进入 DataGrid,这可能是首选或不选择,具体取决于您使用它的情况。

于 2010-01-21T19:17:18.443 回答
10

谢谢你。为了让列的制表位被禁用,我接受了你的答案并稍微修改了它;

     <my:DataGrid Name="datagrid" 
                 AutoGenerateColumns="False" IsReadOnly="True" 
                 CanUserAddRows="False" CanUserDeleteRows="False" 
                 Background="White" 
                 KeyboardNavigation.TabNavigation="Once"
                 SelectionUnit="FullRow"> 
        <my:DataGrid.Columns> 
            <my:DataGridTextColumn x:Name="ID" Header="ID" Width="1*" ></my:DataGridTextColumn> 
            <my:DataGridTextColumn x:Name="Ticker" Header="Ticker" Width="1*">
                    <my:DataGridTextColumn.CellStyle>
                        <Style TargetType="{x:Type my:DataGridCell}">
                            <Setter Property="KeyboardNavigation.IsTabStop" Value="False"></Setter>
                        </Style>
                    </my:DataGridTextColumn.CellStyle>
            </my:DataGridTextColumn> 

            <my:DataGridTextColumn x:Name="OfficialName" Header="Name" Width="3*">
                  <my:DataGridTextColumn.CellStyle>
                        <Style TargetType="{x:Type my:DataGridCell}">
                            <Setter Property="KeyboardNavigation.IsTabStop" Value="False"></Setter>
                        </Style>
                  </my:DataGridTextColumn.CellStyle>
            </my:DataGridTextColumn> 
        </my:DataGrid.Columns> 
    </my:DataGrid>

所以技巧;

  1. SelectionUnit="FullRow" 使 GUI 看起来像是一次做一行(就像我想要的那样)。
  2. 通过将 CellStyle 添加到我想禁用 TabStop 的列(但不包括在我想停止的列中),我可以控制 Tab 键将导航到哪些单元格。- 在列上定义时,KeyboardNavigation.TabNavigation 没有效果。
于 2010-01-22T08:57:53.380 回答
1

我知道这是一个非常古老的问题,但我将其发布在这里以防它对某人有所帮助。虽然公认的答案很好,但我不认为它涵盖了在同一个窗口上有另一个控件的情况,并且您想DataGrid从该控件中选择选项卡。此外,您可能需要原始问题中描述的行为(单个选项卡输入,单个选项卡输出,没有通过单元格/列的选项卡)。该解决方案旨在实现这一目标。

注意:此解决方案假设您希望SelectionUnitFullRowDataGrid.

首先,这是Style适用于DataGrid

<DataGrid.Resources>
    <Style TargetType="DataGridRow">
        <Style.Setters>
            <Setter Property="Focusable" Value="True"/>
        </Style.Setters>
        <Style.Triggers>
            <Trigger Property="IsFocused" Value="True">
                <Setter Property="IsSelected" Value="True"/>
            </Trigger>
        </Style.Triggers>
    </Style>
    <Style TargetType="DataGridCell">
        <Style.Setters>
            <Setter Property="Focusable" Value="False"/>
        </Style.Setters>
    </Style>
</DataGrid.Resources>

这种样式允许关注行但阻止关注单个单元格,从而使焦点与 的 保持SelectionUnit一致FullRow。此样式中设置的触发器是可选的 - 仅当您希望在收到焦点时自动选择行时才需要它。

在我的情况下,我想要单个选项卡输入/选项卡输出行为,所以我还在my = "Once"KeyboardNavigation.TabNavigation上设置了属性。DataGrid

<DataGrid SelectionUnit="FullRow" KeyboardNavigation.TabNavigation="Once">

使用这种方法,一旦接收到焦点,我仍然可以使用向上/向下箭头键循环浏览行DataGrid,但如果我想将焦点移动到选项卡顺序中的下一个控件,我仍然可以快速退出。

于 2019-06-08T18:55:22.850 回答