如何结合两个条件来覆盖数据网格的选定行样式?

Posted

技术标签:

【中文标题】如何结合两个条件来覆盖数据网格的选定行样式?【英文标题】:How can I combine two conditions to override the selected row style of a datagrid? 【发布时间】:2020-01-15 10:42:33 【问题描述】:

我有一个 DataGrid,并且集合中的对象有一个属性 'isvalid' 当一个项目无效(isvalid == false)时,我使用数据触发器将行前景色设置为红色。

这可行,但是当我选择无效行时,数据网格行上的选择样式会覆盖我设置的前景色,并且不再是红色(它只是显示为默认主题前景色)。

如何同时覆盖所选行的前景色样式?

我想把这个结合起来

<Trigger Property="IsSelected" Value="true">
    <Setter Property="Foreground" Value="Red"></Setter>
</Trigger>

满足以下条件

<DataGrid.RowStyle>
    <Style TargetType="DataGridRow" BasedOn="StaticResource MetroDataGridRow">
        <Style.Triggers>
            <DataTrigger Binding="Binding Path=isvalid" Value="false">
                <Setter Property="Foreground" Value="Red"></Setter>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</DataGrid.RowStyle>

无论是否被选中,一行都应该具有红色的前景色(但仅当 isvalid == false 时)

编辑:我尝试了this post的解决方案

<MultiDataTrigger.Conditions>
    <Condition Property="IsSelected" Value="True"/>
    <Condition Binding="Binding Path=isvalid" Value="false" ></Condition>
</MultiDataTrigger.Conditions>

但我明白了

System.InvalidOperationException - 必须具有非空值 '绑定'。

【问题讨论】:

【参考方案1】:

您应该定义一个自定义CellStyle,然后再向其中添加另一个DataTrigger

<DataGrid ...>
    <DataGrid.CellStyle>
        <Style TargetType="x:Type DataGridCell">
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="BorderBrush" Value="Transparent"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="x:Type DataGridCell">
                        <Border BorderBrush="TemplateBinding BorderBrush" BorderThickness="TemplateBinding BorderThickness" Background="TemplateBinding Background" SnapsToDevicePixels="True">
                            <ContentPresenter SnapsToDevicePixels="TemplateBinding SnapsToDevicePixels"/>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Background" Value="DynamicResource x:Static SystemColors.HighlightBrushKey"/>
                    <Setter Property="Foreground" Value="DynamicResource x:Static SystemColors.HighlightTextBrushKey"/>
                    <Setter Property="BorderBrush" Value="DynamicResource x:Static SystemColors.HighlightBrushKey"/>
                </Trigger>
                <Trigger Property="IsKeyboardFocusWithin" Value="True">
                    <Setter Property="BorderBrush" Value="DynamicResource x:Static DataGrid.FocusBorderBrushKey"/>
                </Trigger>
                <MultiTrigger>
                    <MultiTrigger.Conditions>
                        <Condition Property="IsSelected" Value="true"/>
                        <Condition Property="Selector.IsSelectionActive" Value="false"/>
                    </MultiTrigger.Conditions>
                    <Setter Property="Background" Value="DynamicResource x:Static SystemColors.InactiveSelectionHighlightBrushKey"/>
                    <Setter Property="BorderBrush" Value="DynamicResource x:Static SystemColors.InactiveSelectionHighlightBrushKey"/>
                    <Setter Property="Foreground" Value="DynamicResource x:Static SystemColors.InactiveSelectionHighlightTextBrushKey"/>
                </MultiTrigger>
                <Trigger Property="IsEnabled" Value="false">
                    <Setter Property="Foreground" Value="DynamicResource x:Static SystemColors.GrayTextBrushKey"/>
                </Trigger>
                <DataTrigger Binding="Binding isvalid" Value="false">
                    <Setter Property="Foreground" Value="Red"></Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </DataGrid.CellStyle>
    <DataGrid.RowStyle>
        <Style TargetType="DataGridRow" BasedOn="StaticResource MetroDataGridRow">
            <Style.Triggers>
                <DataTrigger Binding="Binding isvalid" Value="false">
                    <Setter Property="Foreground" Value="Red"></Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </DataGrid.RowStyle>
</DataGrid>

【讨论】:

好的,谢谢,通过基于 MetroDataGridCell 的单元格样式并为 isvalid 应用数据触发器,我能够实现与您的代码相同的结果。 xaml 要少得多。

以上是关于如何结合两个条件来覆盖数据网格的选定行样式?的主要内容,如果未能解决你的问题,请参考以下文章

如何根据VS2012上另一个数据网格的选定行在数据网格上显示sql队列结果

如何从网格面板中删除选定的行以及数据库中的相应数据?

如何设置与选定行相邻的 TableView 行的样式?

如何有条件地设置 Dojo 数据网格中的单元格样式?

wpf:DataGrid 禁用选定的行样式 - 或行选择

以新形式编辑选定的数据网格行