WPF中基于RowStyle的CellStyle

CellStyle based on RowStyle in WPF

我有一个 WPF DataGridXAML 中表示。我正在为网格的 TableView 使用 RowStyle,但还需要为特定单元格设置一些属性。我需要这些单元格具有行样式的属性,并在这些单元格样式之上应用额外的属性。

我需要的是这样的东西,虽然这不像它所说的那样有效:

Target type 'CellContentPresenter' is not convertible to base type 'GridRowContent'

<Style x:Key="MyGridRowStyle"
    BasedOn="{StaticResource {themes:GridRowThemeKey ResourceKey=RowStyle}}"
    TargetType="{x:Type dxg:GridRowContent}">
    <Setter Property="Height" 
        Value="25" />
        <Style.Triggers>
        ...
    </Style.Triggers>
</Style>

<Style x:Key="MyCellStyle" 
    BasedOn="{StaticResource MyGridRowStyle}" 
    TargetType="{x:Type dxg:CellContentPresenter}">
    <Style.Triggers>
        ...
    </Style.Triggers>
</Style>

我也尝试过不为 MyCellStyle 指定 BasedOn 属性 但这也不起作用。

我这样使用MyCellStyle

<dxg:GridColumn Header="My Header"
                FieldName="MyFieldName"
                Width="100"
                CellStyle="{StaticResource MyCellStyle}" />

MyGridRowStyleTableView 上这样:

RowStyle="{StaticResource MyGridRowStyle}"

如何使单元格样式仅更改 MyCellStyle 中指定的属性,而将 MyGridRowStyle 中指定的值用于其他属性?

您不能将 CellContentPresenter 样式基于 GridRowContent 样式。这是两种完全不同的类型,只是因为它们可能碰巧有一些同名的属性,所以它们仍然是完全不同的独立属性,彼此之间没有任何关系。

您能做的最好的事情是将公共 定义为单独的资源,并以两种样式使用这些资源,例如:

<Window.Resources>
  <s:Double x:Key="commonHeight">25</s:Double>
  <SolidColorBrush x:Key="commonBg">Red</SolidColorBrush>

  <Style x:Key="MyCellStyle" TargetType="{x:Type dxg:CellContentPresenter}">
    <Setter Property="Height" Value="{StaticResource commonHeight}" />
    <Setter Property="Background" Value="{StaticResource commonBg}" />
  </Style>

  <Style x:Key="MyGridRowStyle" BasedOn="{StaticResource {themes:GridRowThemeKey ResourceKey=RowStyle}}" TargetType="{x:Type dxg:GridRowContent}">
    <Setter Property="Height" Value="{StaticResource commonHeight}" />
    <Setter Property="Background" Value="{StaticResource commonBg}" />
 </Style>
</Window.Resources>

但是您仍然需要在两种样式中定义所有 setter

基于普通的 WPF DataGrid,您可以试试这个并将其扩展为 dxg class DataGridCell 派生自 ContentControl(即 Content 的 child)。 class DataGridRow 派生自 Control.

现在您可以尝试以下操作:

<Style x:Key="BaseStyle" TargetType="Control" >
    <!-- Maybe add BaseStyle / theme here with BasedOn -->
    <Setter Property="Height" Value="25" />
    <!-- Row and Column defaults -->
</Style>
<Style x:Key="MyGridRowStyle" BasedOn="{StaticResource BaseStyle}"
       TargetType="DataGridRow">
    <!-- Row specific implementation -->
</Style>
<Style x:Key="MyCellStyle" BasedOn="{StaticResource BaseStyle}"
       TargetType="DataGridCell">
    <!-- Column specific implementation -->
</Style>

总结: 为你的 BaseStyle 使用 RowColumn classes 的基本类型,并将这个用作 BasedOn。对于 dxg 你可以自己扩展它...

我对这个问题的理解:单元格样式的值应该根据它所在行的样式中的值而改变。

触发值

这是一个简单的工作示例(通过将 DataGridRow 背景更改为红色来测试它,您会注意到单元格的前景更改为蓝色):

 <DataGrid>
    <DataGrid.RowStyle>
        <Style TargetType="DataGridRow">
            <Setter Property="Background" Value="White"/>
        </Style>
    </DataGrid.RowStyle>
    <DataGrid.CellStyle>
        <Style TargetType="DataGridCell">
            <Style.Triggers>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=DataGridRow, Mode=FindAncestor}, Path=Background}" Value="Red">
                    <Setter Property="Foreground" Value="Blue"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </DataGrid.CellStyle>
</DataGrid>

您可以进行类似的绑定,直接将 CellStyle 的属性设置为其所在行的属性值。

相对直接绑定到一个属性

<DataGrid x:Name="dataGrid1" ItemsSource="{Binding Collection}">
    <DataGrid.RowStyle>
        <Style TargetType="DataGridRow">
            <Setter Property="Height" Value="20"/>
        </Style>
    </DataGrid.RowStyle>
    <DataGrid.CellStyle>
        <Style TargetType="DataGridCell">
            <Setter Property="FontSize" Value="{Binding RelativeSource={RelativeSource AncestorType=DataGridRow, Mode=FindAncestor}, Path=Height}"/>
        </Style>
    </DataGrid.CellStyle>
</DataGrid>

说明

RelativeBinding 之所以有效,是因为 DataGridCells 最终是 DataGridRows 的子代,如 DataGrid 可视化树的屏幕截图所示: