禁用WPF数据网格中列之间的tabstop

时间:2010-01-21 17:19:12

标签: wpf xaml wpfdatagrid tabstop

我有一个带有多个列的WPF Toolkit数据网格。我试图获得一个行为,您可以使用选项卡切换到网格,然后使用单个选项卡再次选项卡。例如。我不希望选中网格的所有列或单元格,只需进入一次,然后退出。

是否有一个简单的解决方案,我尝试将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>

3 个答案:

答案 0 :(得分:19)

有趣的是,直接在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,这可能是首选或不首选,具体取决于您使用它的情况。

答案 1 :(得分:10)

谢谢rmoore。为了让列禁用标签停止,我接受了你的回答并稍微修改了一下;

     <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-key将导航到哪些单元格。 - 在列上定义时,KeyboardNavigation.TabNavigation没有效果。

答案 2 :(得分:0)

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

注意:该解决方案是假设您希望SelectionUnitFullRow中成为DataGrid

首先,这是要应用于Style的{​​{1}}:

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> 的{​​{1}}保持一致。此样式内的触发器设置是可选的-仅当您希望在其获得焦点时自动选择该行时才需要。

在我的情况下,我希望使用单个tab in / tab out行为,因此我还在SelectionUnit =“ Once”上设置了FullRow属性。

KeyboardNavigation.TabNavigation

使用这种方法,一旦DataGrid获得焦点,我仍然可以使用向上/向下箭头键在各行之间循环,但是如果要将焦点移至菜单中的下一个控件,仍然可以快速跳出。制表符顺序。