在 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:不要忘记将事件处理程序添加到您的 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。

以上是关于在 FullRow 选择模式下禁用 DataGrid 当前单元格边框的主要内容,如果未能解决你的问题,请参考以下文章

在 Android 的开发模式下禁用 Firebase

如何禁用消息“在维护模式下运行。联机。”在维护模式?

新的 Firebase Crashlytics 在调试模式下禁用

如何在调试模式下,在 react-native-firebase 中禁用 Crashlytics?

Visual Studio 在调试模式下禁用 TRACE

禁用 UIButton 注册触摸并引发错误