这是我上一个问题之后的问题,你可以在这里找到它
。现在我定义了一个DataGrid
,每一列都有一个特定的ElementStyle
(它只是定义了里面的TextBlock
s,用粗体&白色——稍后会解决这个问题)
现在我有两个问题
第一个问题(解决)
当我碰巧为单元格设置背景时,它会覆盖默认样式,并且当单元格高亮显示时背景保持不变。
样式的一个例子:
<!-- Green template for market-related -->
<ControlTemplate x:Key="Green" TargetType="{x:Type tk:DataGridCell}">
<Grid Background="Green">
<ContentPresenter
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
我自然会说这是"正常的",因为我把Grid
的背景设置为绿色。因此,我尝试这样做:
<!-- Light green template for sophis-related -->
<ControlTemplate x:Key="LightGreen" TargetType="{x:Type tk:DataGridCell}">
<Grid Background="LightGreen">
<Grid.Resources>
<Style TargetType="{x:Type Grid}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type tk:DataGridCell}},
Converter={StaticResource DebugConverter}}" Value="True">
<Setter Property="Grid.Background" Value="#FF3774FF" />
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
这个也不行。正如你所看到的,我放了一个DebugConverter,这样我就可以检查触发器是否被调用了,情况就是这样,但是。背景没有改变(Snoop证实了这一点…)
第三次尝试:
<!-- Light green template for sophis-related -->
<ControlTemplate x:Key="LightGreen" TargetType="{x:Type tk:DataGridCell}">
<ControlTemplate.Resources>
<Style TargetType="{x:Type tk:DataGridCell}">
<Setter Property="Background" Value="LightGreen" />
</Style>
</ControlTemplate.Resources>
<Grid>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
…不显示背景(保持透明)
所以我认为我在这里工作在错误的方式,我想知道我应该怎么做,只是定义"未选择"模板。我想说我可能需要定义一个基于"经典"风格的样式,但是,我该怎么做呢?我尝试添加TemplateBindings,但没有成功
** EDIT: Solution**
正如H B在他的回答中所建议的,问题来自DependencyProperty Precedence,下面是解决方案:
<!-- Light green template for sophis-related -->
<ControlTemplate x:Key="LightGreen" TargetType="{x:Type tk:DataGridCell}">
<Grid>
<Grid.Resources>
<Style TargetType="{x:Type Grid}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type tk:DataGridCell}},
Converter={StaticResource DebugConverter}}" Value="True">
<Setter Property="Grid.Background" Value="#FF316AC5" />
</DataTrigger>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type tk:DataGridCell}},
Converter={StaticResource DebugConverter}}" Value="False">
<Setter Property="Grid.Background" Value="LightGreen" />
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
第二个问题
现在,让我们来谈谈Triggers
。
基本上,我想做的是定义特定的Triggers
到我的ElementStyle
,所以字体颜色是白色的,如果单元格的背景是红色或绿色(这样做的唯一目的是有一个更好的可读性,红色和绿色有点暗,黑色字体在黑暗的背景导致一个很好的失败:p)
Edit似乎我不够清楚:以下样式是通过属性DataGridTextColumn.ElementStyle
应用于数据网格的每个项目的样式。下面是处理
void VolatilityDataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
DataGridTextColumn column = e.Column as DataGridTextColumn;
column.ElementStyle = s_boldCellStyle;
// Other stuff here...
}
我是这样做的:
<!-- Cell style for colored matrix-->
<Style x:Key="BoldCellStyle" TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding Background, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type tk:DataGridCell}}}"
Value="Red">
<Setter Property="Foreground" Value="White" />
</DataTrigger>
<DataTrigger Binding="{Binding Background, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type tk:DataGridCell}},
Converter={StaticResource DebugConverter}}"
Value="Green">
<Setter Property="Foreground" Value="White" />
</DataTrigger>
</Style.Triggers>
<Setter Property="FontWeight" Value="Bold"/>
</Style>
…这行不通。奇怪的是,经过转换器的只是透明的背景色。我肯定错过了什么!顺便说一句,我也尝试了经典的触发器,也没有成功,我在这里使用DataTriggers
,所以我可以调试绑定值!
现在我已经被困了三天多了,我开始抓狂了…希望Stackoverflow社区能拯救我:)
谢谢!
编辑
好的,更新。我明白为什么我的Trigger
不工作。背景实际上是在Grid
上而不是在DataGridCell
上设置的。因此,我没有在那里设置任何颜色是正常的。
然而,我运行了一些测试,发现当绑定设置时,TextBlock
还没有任何父(Parent
= null)。绑定到Grid
类型的RelativeSource
将绑定到…整个DataGrid
项目展示。我不知道现在该怎么办,因为从实际的TextBlock
样式来看,我无法到达父Grid
,因此无法解决我应该根据背景显示什么颜色。此外,我不能改变我的ControlTemplate
的字体颜色,因为DataGrid
想要一个Style
的每一列,这覆盖了模板的默认样式(参见我之前的问题和它的答案)所以…我又卡住了!
依赖属性值优先级
:
<Grid Background="LightGreen">
<Grid.Resources>
<Style TargetType="{x:Type Grid}">
<!-- Trigger Stuff -->
</Style>
</Grid.Resources>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
必须是:
<Grid>
<Grid.Resources>
<Style TargetType="{x:Type Grid}">
<Setter Property="Background" Value="LightGreen"/>
<!-- Trigger Stuff -->
</Style>
</Grid.Resources>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
不确定你的第二个问题,可能是一个相关的问题,我建议初学者设置TextElement.Foreground
而不是Foreground
。获得Transparent
作为值不是很有帮助,您为DataGridCell
使用什么控制模板?如果是自定义的,Background
是否通过TemplateBinding
正确连接?
只要使用Background
属性就可以工作,所以如果你有一个ControlTemplate
在内部设置东西,你需要外部化它。正常DataGrid
示例:
<DataGrid.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="Background" Value="LightGreen"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Content}" Value="Apple">
<Setter Property="Background" Value="Red"/>
</DataTrigger>
<DataTrigger Binding="{Binding Content}" Value="Tomato">
<Setter Property="Background" Value="Green"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.CellStyle>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding Background, RelativeSource={RelativeSource AncestorType={x:Type DataGridCell}}}" Value="Red">
<Setter Property="Foreground" Value="White"/>
</DataTrigger>
<DataTrigger Binding="{Binding Background, RelativeSource={RelativeSource AncestorType={x:Type DataGridCell}}}" Value="Green">
<Setter Property="Foreground" Value="White"/>
</DataTrigger>
</Style.Triggers>
<Setter Property="FontWeight" Value="Bold"/>
</Style>
因此,如果CellStyle
设置ControlTemplate
的属性需要通过TemplateBinding连接。例如
<DataGrid.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Grid Background="{TemplateBinding Background}">
<ContentPresenter />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Background" Value="LightGreen"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Content}" Value="Apple">
<Setter Property="Background" Value="Red"/>
</DataTrigger>
<DataTrigger Binding="{Binding Content}" Value="Tomato">
<Setter Property="Background" Value="Green"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.CellStyle>
不要在模板内触发,否则会很乱。