在 WPF 数据网格中的列之间禁用制表位

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2111281/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 21:26:47  来源:igfitidea点击:

Disable tabstop between columns in a WPF datagrid

wpfxamlwpfdatagridtabstop

提问by Thies

I have a WPF Toolkit datagrid with mulitple columns. I am trying to get a behaviour where you can tab into the grid using tab, then tab out again using a single tab. E.g. I do not want to tab through all the columns or cells of the grid, just once in, and once out.

我有一个带有多个列的 WPF Toolkit 数据网格。我正在尝试获得一种行为,您可以使用选项卡进入网格,然后使用单个选项卡再次退出。例如,我不想浏览网格的所有列或单元格,只一次进入,一次退出。

Is there a simple solution, I have tried setting the TabNavigation to Once, along with disabling TabStop (not shown in code below) and setting TabNavigation on the columns to None, but without success.

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

Is there something I am missing or do I need to handle the Tab-key in code?

有什么我遗漏的地方还是我需要处理代码中的 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>

回答by rmoore

It's interesting that setting the KeyboardNavigation directly on the DataGridTextColumn's doesn't work. An alternative that should work is to set up a DataGridCell style.

有趣的是,直接在 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>

Attaching this to the DataGrid will ensure that a cell is only a TabStop if it is already selected. However, if you are selecting full rows and don't have SelectionUnit="Cell" set on the DataGrid, it will still cycle through each column of the currently selected row.

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

Instead, we can create multiple CellStyles as resources within the DataGrid:

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

<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>

Now we have a style being applied to all DataGridCells by default and turning off TabStop, and a keyed style that allows selection when the Cell (or whole Row) is selected. Applying this style to only a single column will give us the same single-tab-in effect while allowing the whole row and all of it's columns to be selected.

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

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

This does also stop tabbing into the DataGrid if nothing is selected, which may be preferred or not depending on the situation you are using it in.

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

回答by Thies

Thank you rmoore. To get the tab stop to be disabled for columns I took your answer and modified it slightly;

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

     <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>

So tricks;

所以技巧;

  1. SelectionUnit="FullRow" makes the GUI look like you are doing things one row at a time (like I wanted).
  2. By adding a CellStyle to the columns I want to disable TabStop in (but not including it in those I would like to stop in) allowed me to take control over which cells that tab-key would navigate into. - The KeyboardNavigation.TabNavigation not having an effect when defined on columns.
  1. SelectionUnit="FullRow" 使 GUI 看起来就像您一次做一行(就像我想要的那样)。
  2. 通过向列中添加 CellStyle,我想禁用 TabStop(但不包括在我想要停止的列中)允许我控制 Tab 键将导航到的单元格。- 在列上定义时,KeyboardNavigation.TabNavigation 没有效果。

回答by Mash

I know this is a really old question, but I'm posting this here in case it helps someone. While the accepted answer is good, I don't believe it covers the case where there's another control on the same window, and you would like to tab into the DataGridfrom that control. Additionally, you may want the behavior as described in the original question (single tab in, single tab out, no tabbing through cells/columns). This solution aims to achieve this.

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

Note:This solution is assuming you want your SelectionUnitto be FullRowin your DataGrid.

注意:此解决方案是假设你希望你的SelectionUnitFullRow你的DataGrid

First, here is the Styleto apply to the DataGrid:

首先,这是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>

This style allows focus on rows but prevents focus on individual cells, which keeps the focus consistent with the SelectionUnitof FullRow. The trigger set inside this style is optional - it is only needed if you want to automatically select the row when it receives focus.

这种风格允许在行焦点,但防止专注于单个细胞,这使与一致的焦点SelectionUnitFullRow。此样式中设置的触发器是可选的 - 仅当您希望在获得焦点时自动选择行时才需要它。

In my case, I wanted the single tab in / tab out behavior, so I also set the KeyboardNavigation.TabNavigationproperty on my DataGrid= "Once."

就我而言,我想要单个选项卡输入/选项卡退出行为,因此我还在KeyboardNavigation.TabNavigationmy DataGrid= "Once"上设置了该属性。

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

With this approach, I can still use the up/down arrow keys to cycle through rows once the DataGridreceives focus, but I can still tab out quickly if I want to move focus to the next control in the tab order.

使用这种方法,一旦DataGrid接收到焦点,我仍然可以使用向上/向下箭头键在行之间循环,但是如果我想将焦点移到 Tab 键顺序中的下一个控件,我仍然可以快速 Tab 键。