【问题标题】:Disable DataGrid current cell border in FullRow selection mode在 FullRow 选择模式下禁用 DataGrid 当前单元格边框
【发布时间】:2011-05-31 15:33:15
【问题描述】:

我在行选择模式下使用 DataGrid(即SelectionUnit="FullRow")。我只是想在用户突出显示一行时删除当前单元格周围的边框,以便进行真正的全行选择(并且没有单元格级别选择)。我不介意网格保持当前单元格的概念,我只想删除那个讨厌的当前单元格边框,也许是通过更改当前单元格的样式。最简单的方法是什么?

【问题讨论】:

  • 我以为我想要这个(并且还避免 Tab/Shift-Tab 键移动到下一个/前一个单元格作为 Mark A. Donohoe's A 的第二部分 2015 年 6 月 4 日 10 点:34 确实),但是我已经意识到,当水平滚动在DataGrid 上启用并处于活动状态时,我仍然希望右/左键移动到下一个/上一个单元格,并且这样做时,我仍然需要当前单元格边界。 Donohoe 的简化/固定为 just 在非第一列上设置“IsTabStop” = false 这样做(同时仍然允许通过单击任何与仅第一列和下一行/前一行移动通过键盘通过向下/向上键)。

标签: wpf wpfdatagrid wpf-4.0


【解决方案1】:

如果您不想弄乱 XAML 样式,您可以做这个简单的 hack。它不如 XAML 样式好用,但您可以尝试一下,看看它是否适合您。简单地点击单元格很好,但如果你尝试拖动单元格,这不会在之后移除焦点(尽管我很确定你可以添加另一个案例来检查它)。

private void YourDataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    YourDataGrid.Focus();
}

PS:不要忘记将事件处理程序添加到您的 DataGridSelectionChanged 属性中。

【讨论】:

    【解决方案2】:

    真正的答案是:

    <!-- put it in your cell style -->
    <DataTrigger Binding="{Binding SelectionUnit, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" Value="FullRow">
        <Setter Property="BorderThickness" Value="0" />
    </DataTrigger>
    

    问题是关于仅在 FullRow 选择模式下禁用它,但其他答案提供了一种解决方案,即使在单元格选择模式下也可以完全禁用它。

    回答一个非常古老的问题,但信不信由你 WPF 和 WinForms 现在仍在使用。

    【讨论】:

      【解决方案3】:

      在这里看到另一个很接近的答案,但它并没有摆脱焦点矩形。以下是消除所有边界的方法。

      <DataGrid.Resources>
          <Style TargetType="{x:Type DataGridCell}">
              <Setter Property="BorderThickness" Value="0" />
              <Setter Property="FocusVisualStyle" Value="{x:Null}" />
          </Style>
      </DataGrid.Resources>
      

      另外,因为从技术上讲,这些单元格仍然会获得焦点(您只是看不到它),为了使 tab 键前进到下一行而不是下一个单元格,我根据上面定义了一个单元格样式,但是还添加了以下...

      <DataGrid.Resources>
          <Style x:Key="NoFocusDataGridCell" TargetType="{x:Type DataGridCell}" BasedOn="{StaticResource {x:Type DataGridCell}}">
              <Setter Property="Focusable"        Value="False" />
              <Setter Property="IsTabStop"        Value="False" />
              <Setter Property="IsHitTestVisible" Value="False" />
          </Style>
      </DataGrid.Resources>
      

      ...然后我将其应用于除第一列定义之外的所有内容。这样,tab 键前进到下一行,而不是下一个单元格。

      然而,回到边界。如果您想隐藏它们,但仍希望它们成为间距原因的布局的一部分,请将上面的内容更改为...

      <DataGrid.Resources>
          <Style TargetType="{x:Type DataGridCell}">
              <Setter Property="BorderBrush" Value="Transparent" />
              <Setter Property="FocusVisualStyle" Value="{x:Null}" />
          </Style>
      </DataGrid.Resources>
      

      享受吧! :)

      【讨论】:

      • 这更接近,但仍然有一个警告:如果您单击第 0 列,您将获得活动的选择高亮画笔(如预期的那样),但单击第 1 列+您将获得非活动的选择高亮画笔(意外)。不活动的画笔会一直保持(单击其他行)直到您单击第 0 列。然后活动的画笔会一直保持直到 DataGrid 失去焦点。
      • 有趣。我以前没有看到,但我现在肯定会尝试。但是,我添加它的原因是为了修复标签顺序。也就是说,也许修复就像将其从 focusable = false 更改为 istabstop = false 一样简单。它应该达到同样的效果。
      • 我刚刚尝试了IsTabStop="False" 调整,它似乎涵盖了所有情况。从技术上讲,当您单击时,非第一列单元格会获得焦点,您可以向左/向右箭头以将焦点更改为其他单元格,但制表符转到下一行的第一个单元格或下一个控件(如果最后一行的单元格中的一个是焦点) .但是,我怀疑这是一个问题。也许对于屏幕阅读器?无论如何,谢谢!
      • 我以为我想要 OP 想要的东西(并且还避免 Tab/Shift-Tab 键移动到下一个/前一个单元格作为 Mark A. Donohoe 的 A 在 2015 年 6 月 4 日的第二部分在 10:34 确实),但我已经意识到,当水平滚动在 DataGrid 上启用并处于活动状态时,我仍然希望右/左键移动到下一个/上一个单元格,并且这样做时,我仍然需要当前单元格边界。 Donohoe 的简化/固定为仅在非第一列上设置“IsTabStop” = false 这样做(同时仍然允许通过单击任何行来选择行,而仅允许通过向下/向上键通过键盘移动下一行/上一行) .
      【解决方案4】:

      您可以将DataGridCellBorderThickness 设置为0

      <DataGrid ...
                SelectionUnit="FullRow">
          <DataGrid.CellStyle>
              <Style TargetType="DataGridCell">
                  <Setter Property="BorderThickness" Value="0"/>
                  <!-- Update from comments.
                       Remove the focus indication for the selected cell -->
                  <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
              </Style>
          </DataGrid.CellStyle>
          <!-- ... -->
      </DataGrid>
      

      【讨论】:

      • 如果用户使用箭头键,这不起作用。虚线选择边框仍然出现在单元格中。
      • @Michael Yanni:你说的是FocusVisualStyle。要禁用它,请在 CellStyle 中将其设置为 null,例如 &lt;Setter Property="FocusVisualStyle" Value="{x:Null}"/&gt;
      • 如何在边框设置为 0 的情况下恢复单元格的缺失间距?
      • @LonelyPixel,不是将粗细设置为零,而是将边框画笔设置为透明。
      • 这实际上并不能阻止这些细胞集中注意力。你只是没有看到它。因此,tab 键看起来无法正常工作,因为焦点在单元格而不是行中循环。我已经添加了一个解决这个问题的答案。
      【解决方案5】:

      如果您使用的是xceed DataGridControl,则将NavigationBehavior 设置为RowOnly

      <xcdg:DataGridControl NavigationBehavior="RowOnly" SelectionMode="Single"  ....
      

      【讨论】:

        【解决方案6】:

        如果您只想在单元格可编辑和选中时显示边框,您可以覆盖 DataGridCell 模板并为单元格 IsSelected 而不是 IsReadOnly 添加一个多重触发器。如果为列或 DataGrid 设置 IsReadOnly = true,则单元格不会显示边框

        <ControlTemplate x:Key="MellowDataGridCellTemplate" TargetType="{x:Type DataGridCell}">
            <Grid>
                <ContentPresenter VerticalAlignment="Center" />
                <Rectangle Name="FocusVisual" Stroke="White" StrokeThickness="1" Fill="Transparent" HorizontalAlignment="Stretch" 
                                   VerticalAlignment="Stretch" IsHitTestVisible="false" Opacity="0" />
        
            </Grid>
            <ControlTemplate.Triggers>
                <MultiTrigger>
                    <MultiTrigger.Conditions>
                        <Condition Property="IsReadOnly" Value="False" />
                        <Condition Property="IsSelected" Value="True" />
                    </MultiTrigger.Conditions>
                    <Setter TargetName="FocusVisual" Property="Opacity" Value="1"/>
                </MultiTrigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
        

        在样式中使用模板

        <Style TargetType="{x:Type DataGridCell}" x:Key="MellowGridDataGridCell">
            <Setter Property="Template" Value="{StaticResource MellowDataGridCellTemplate}" />
        </Style>
        

        并使用样式

        <DataGrid CellStyle={StaticResource MellowGridDataGridCell >
            ...
        </DataGrid>
        

        【讨论】:

          【解决方案7】:
          <Style x:Key="DataGrid" TargetType="DataGrid">
              <Setter Property="CellStyle">
                  <Setter.Value>
                      <Style TargetType="DataGridCell">
                          <Setter Property="BorderThickness" Value="0"/>
                          <Setter Property="Foreground" Value="{Binding Foreground, RelativeSource={RelativeSource TemplatedParent}}" />
                          <Setter Property="Background" Value="{Binding Background, RelativeSource={RelativeSource TemplatedParent}}" />
                      </Style>
                  </Setter.Value>
              </Setter>
          </Style>
          

          【讨论】:

          • 添加这两行有助于保持 ResourceDictionary 应用的样式,感谢@marius。
          猜你喜欢
          • 2011-07-25
          • 1970-01-01
          • 2023-02-04
          • 2022-06-14
          • 2016-08-27
          • 2013-09-19
          • 1970-01-01
          • 1970-01-01
          • 2022-01-12
          相关资源
          最近更新 更多