WPF中基于RowStyle的CellStyle
CellStyle based on RowStyle in WPF
我有一个 WPF
DataGrid
在 XAML
中表示。我正在为网格的 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}" />
和 MyGridRowStyle
在 TableView
上这样:
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
使用 Row
和 Column
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 可视化树的屏幕截图所示:
我有一个 WPF
DataGrid
在 XAML
中表示。我正在为网格的 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}" />
和 MyGridRowStyle
在 TableView
上这样:
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
使用 Row
和 Column
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 可视化树的屏幕截图所示: