当 SelectionMode 设置为 Cell 时,如何突出显示 WPF DataGrid 中的一行

Posted

技术标签:

【中文标题】当 SelectionMode 设置为 Cell 时,如何突出显示 WPF DataGrid 中的一行【英文标题】:How do I highlight a row in the WPF DataGrid when SelectionMode is set to Cell 【发布时间】:2015-08-28 14:58:47 【问题描述】:

我有一个 DataGrid 绑定到 WPF 应用程序中的 DataTable。 DataGrid 的 SelectionUnit 必须设置为 Cell,但我还想为整行添加一个微妙的突出显示,以便在宽 DataGrids 上,当用户滚动所选单元格时,他们可以仍然看到突出显示的行。

这有点问题,因为 DataGridRow 的 IsSelected 属性永远不会设置为 true,因为没有选择 Row,而是选择了 Cell。

我不介意它是粘性 RowSelector 中的一个小箭头,还是应用于整个 Row 的突出显示。只需要某种方式突出显示选择了哪一行。

【问题讨论】:

Might be related 感谢@MikeEason - 解决方案是更改 SelectionUnit,但我需要保留单个单元格选择。 【参考方案1】:

我在这里玩了一点,没什么特别的,但它是一个工作版本:

    <Style TargetType="DataGridCell">
       <EventSetter Event="Selected" Handler="EventSetter_OnHandlerSelected"/>
       <EventSetter Event="LostFocus" Handler="EventSetter_OnHandlerLostFocus"/>
    </Style>

这是代码隐藏:

    private void EventSetter_OnHandlerSelected(object sender, RoutedEventArgs e)
    
        DataGridRow dgr = FindParent<DataGridRow>(sender as DataGridCell);
        dgr.Background = new SolidColorBrush(Colors.Red);
    

    private void EventSetter_OnHandlerLostFocus(object sender, RoutedEventArgs e)
    
        DataGridRow dgr = FindParent<DataGridRow>(sender as DataGridCell);
        dgr.Background = new SolidColorBrush(Colors.White);
    

这是获取父级的辅助方法:

    public static T FindParent<T>(DependencyObject child) where T : DependencyObject
    
        //get parent item
        DependencyObject parentObject = VisualTreeHelper.GetParent(child);

        //we've reached the end of the tree
        if (parentObject == null) return null;

        //check if the parent matches the type we're looking for
        T parent = parentObject as T;
        if (parent != null)
            return parent;
        else
            return FindParent<T>(parentObject);
    

这不是 MVVM,但考虑到我们只是在使用 View 元素 .. 我认为这一次不是必须的。 所以基本上,在第一次选择时,您为该行着色,在失去焦点时转回白色前一个并更改新选择的颜色。

【讨论】:

【参考方案2】:

这很有效,并且与 MVVM 一样。为了更好的可读性,我使用了ExpressionConverter,这是一种让 XAML 更具可读性但更容易出错的惊人方式。我还对其进行了一些更改以支持多重绑定,但这是题外话,您可以从代码中获得基本思想:从行和网格的 CurrentCell 属性中获取数据上下文,并比较它们是否相同。

<DataGrid.Resources>
    <Style TargetType="x:Type DataGridRow">
        <Style.Triggers>
            <DataTrigger Value="True">
                <DataTrigger.Binding>
                    <MultiBinding Converter="amazing:ExpressionConverter 'x[0] == x[1]'">
                        <Binding RelativeSource="RelativeSource Self" Path="DataContext"></Binding>
                        <Binding ElementName="Grid" Path="CurrentCell" Converter="amazing:ExpressionConverter 'x.Item'"></Binding>
                    </MultiBinding>
                </DataTrigger.Binding>
                <Setter Property="Background" Value="Red"></Setter>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</DataGrid.Resources>

【讨论】:

【参考方案3】:

我在 MSDN 上找到了一个很好的解决方案。链接到我对类似问题的回答:

Highlight row when SelectionUnit is set to Cell

【讨论】:

以上是关于当 SelectionMode 设置为 Cell 时,如何突出显示 WPF DataGrid 中的一行的主要内容,如果未能解决你的问题,请参考以下文章

wpf datagrid 单元格如何默认单击一次点中

如何在 WPF 数据网格中选择单个单元格?

DataGridView 添加多列

设置cell的属性text label的显示文本

iOSUITableview cell 顶部空白的n种设置方法

poi 复制带公式的cell,怎么把公式对应的参数设置好