在 FullRow 选择模式下禁用 DataGrid 当前单元格边框
Posted
技术标签:
【中文标题】在 FullRow 选择模式下禁用 DataGrid 当前单元格边框【英文标题】:Disable DataGrid current cell border in FullRow selection mode 【发布时间】: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 这样做(同时仍然允许通过单击任何与仅第一列和下一行/前一行移动通过键盘通过向下/向上键)。
【参考方案1】:
如果您不想弄乱 XAML 样式,您可以做这个简单的 hack。它不如 XAML 样式好用,但您可以尝试一下,看看它是否适合您。简单地点击单元格很好,但如果你尝试拖动单元格,这不会在之后移除焦点(尽管我很确定你可以添加另一个案例来检查它)。
private void YourDataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
YourDataGrid.Focus();
PS:不要忘记将事件处理程序添加到您的 DataGrid
的 SelectionChanged
属性中。
【讨论】:
【参考方案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】:
您可以将DataGridCell
的BorderThickness
设置为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,例如 <Setter Property="FocusVisualStyle" Value="x:Null"/>
如何在边框设置为 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。以上是关于在 FullRow 选择模式下禁用 DataGrid 当前单元格边框的主要内容,如果未能解决你的问题,请参考以下文章
新的 Firebase Crashlytics 在调试模式下禁用