【问题标题】:Disable tabstop between columns in a WPF datagrid在 WPF 数据网格中的列之间禁用制表符
【发布时间】:2011-01-07 20:25:41
【问题描述】:

我有一个包含多列的 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>

【问题讨论】:

标签: wpf xaml wpfdatagrid tabstop


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

         <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 无效。

    【讨论】:

      【解决方案3】:

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

      注意:此解决方案假设您希望您的SelectionUnit 在您的DataGrid 中成为FullRow

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

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

      在我的例子中,我想要单个 tab in / tab out 行为,所以我还在 DataGrid 上设置了 KeyboardNavigation.TabNavigation 属性 = "Once"。

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

      使用这种方法,一旦DataGrid 获得焦点,我仍然可以使用向上/向下箭头键循环浏览行,但如果我想将焦点移到 Tab 键顺序中的下一个控件,我仍然可以快速跳出.

      【讨论】:

      • 这对我来说不是很有效,但它很接近!当 DataGrid 中存在多行时,第一次进入 DataGrid 会选择第一行,而下一个选项卡会选择 DataGrid 之外的选项卡。但是,如果您选择第二行和选项卡足以循环回到 DataGrid,它会重新选择第一行。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多