样式化在ContentPresenter中自动生成的文本块

Dam*_*cus 5 wpf datagrid datatemplate controltemplate

正如我所看到的,很多人遇到了这个确切的问题,但我无法理解为什么我的情况不起作用而且它开始让我发疯.

上下文:我有一个DataGrid根据每个单元格的值着色的.因此,我有一个动态样式解析用于每个单元格的实际模板.背景现在相应地起作用.

新问题:当我有一个深色背景时,我希望字体颜色为白色,字体粗细为粗体,以便文本可以正确读取.而且......我无法正确设计它.

我读了一些关于它的Stackoverflow帖子:

这个适合我的问题,但没有提供任何工作解决方案 这一个也很清楚,细节但是...... 这个问题和我几乎一样但是......解决方案不起作用

这是我到目前为止尝试的内容:

<!-- Green template-->
    <ControlTemplate x:Key="Green" TargetType="{x:Type tk:DataGridCell}">
        <Grid Background="Green">
            <ContentPresenter
                            HorizontalAlignment="Center"
                                      VerticalAlignment="Center">
                <ContentPresenter.Resources>
                    <Style BasedOn="{StaticResource BoldCellStyle}" TargetType="{x:Type TextBlock}" />
                </ContentPresenter.Resources>
            </ContentPresenter>
        </Grid>
    </ControlTemplate>
Run Code Online (Sandbox Code Playgroud)

不行.背景为绿色,但文字保持黑色而不是粗体.

BTW,BoldCellStyle尽可能简单:

<Style x:Key="BoldCellStyle" TargetType="{x:Type TextBlock}">
    <Setter Property="FontWeight" Value="Bold"/>
    <Setter Property="Foreground" Value="White" />
</Style>
Run Code Online (Sandbox Code Playgroud)

好的.第二次尝试(这是一个真正的愚蠢但很好......)

<!-- Green template  -->
    <ControlTemplate x:Key="Green" TargetType="{x:Type tk:DataGridCell}">
        <Grid Background="Green">
            <ContentPresenter
                            HorizontalAlignment="Center"
                                      VerticalAlignment="Center">
                <ContentPresenter.Resources>
                    <Style x:Key="BoldCellStyle" TargetType="{x:Type TextBlock}">
                        <Setter Property="FontWeight" Value="Bold"/>
                        <Setter Property="Foreground" Value="White" />
                    </Style>

                </ContentPresenter.Resources>
            </ContentPresenter>
        </Grid>
    </ControlTemplate>
Run Code Online (Sandbox Code Playgroud)

也不起作用.

然后,我试着玩这个ContentPresenter属性:

<!-- Green template -->
<ControlTemplate x:Key="Green" TargetType="{x:Type tk:DataGridCell}">
    <Grid Background="Green">
        <ContentPresenter TextElement.FontWeight="Bold" TextElement.Foreground="White" TextBlock.Foreground="White"
                        HorizontalAlignment="Center"
                                  VerticalAlignment="Center" />
    </Grid>
</ControlTemplate>
Run Code Online (Sandbox Code Playgroud)

并且......正如您所料,这甚至都不起作用.

好奇,我使用Snoop浏览界面的所有组件.在前两种情况下,探听居然让我发现,每个单元是Grid一个ContentPresenter包含TextBlock与实际Style...但是... TextBlock的性质不适用,并且FontWeight仍然是正常的.

最后一个案例,更令人震惊的是,我可以看到snoop告诉我,我们实际上有一个ContentPresenter具有正确属性(即TextElement.FontWeight="Bold"),但自动生成的TextBlock是 - 仍然 - 没有样式.

我无法得到我在这里失踪的东西.我试过,因为你几乎可以看到我在这里可能做的所有事情,并且TextBlocks保持非格式化.

这有什么想法吗?再次感谢!

Fre*_*lad 2

派生DataGridColumnsDataGridBoundColumn(除了)的 具有一个在创建时应用于 的DataGridTemplateColumn属性。例如它看起来像这样ElementStyleTextBlockDataGridTextColumn

static DataGridTextColumn()
{
    ElementStyleProperty.OverrideMetadata(typeof(DataGridTextColumn),
        new FrameworkPropertyMetadata(DefaultElementStyle));
    // ...
}
Run Code Online (Sandbox Code Playgroud)

它覆盖 的元数据ElementStyle并提供新的默认值 ,DefaultElementStyle这基本上只是设置 的默认边距TextBlock

public static Style DefaultElementStyle
{
    get
    {
        if (_defaultElementStyle == null)
        {
            Style style = new Style(typeof(TextBlock));
            // Use the same margin used on the TextBox to provide space for the caret
            style.Setters.Add(new Setter(TextBlock.MarginProperty, new Thickness(2.0, 0.0, 2.0, 0.0)));
            style.Seal();
            _defaultElementStyle = style;
        }
        return _defaultElementStyle;
    }
}
Run Code Online (Sandbox Code Playgroud)

DataGridCell每次创建新样式时都会在代码中设置此样式element.Style = style;,并且这会覆盖您尝试设置的样式,即使您尝试隐式设置它也是如此。

据我所知,您必须为您的专栏重复此操作

<DataGridTextColumn Header="Column 1" ElementStyle="{StaticResource BoldCellStyle}" .../>
<DataGridTextColumn Header="Column 2" ElementStyle="{StaticResource BoldCellStyle}" .../>
Run Code Online (Sandbox Code Playgroud)