设置 ContentPresenter 中自动生成的文本块的样式

发布于 2024-11-30 04:13:44 字数 3593 浏览 1 评论 0原文

正如我所看到的,很多人都遇到了这个问题,但我不明白为什么我的案例不起作用,它开始让我发疯。

上下文:我有一个 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>

不起作用。背景是绿色的,但文本保持黑色和绿色。不大胆。

顺便说一句,BoldCellStyle 非常简单:

<Style x:Key="BoldCellStyle" TargetType="{x:Type TextBlock}">
    <Setter Property="FontWeight" Value="Bold"/>
    <Setter Property="Foreground" Value="White" />
</Style>

好的。第二次尝试(这是一次非常愚蠢的尝试,但是……)

<!-- 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>

也不起作用。

然后,我尝试使用 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>

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

出于好奇,我使用 Snoop 浏览了界面的所有组件。 在前两种情况下,Snoop 实际上向我展示了每个单元格都是一个 Grid,其中包含一个 ContentPresenter,其中包含 TextBlock 和实际的 Style 但是... TextBlock 的属性不适用,并且 FontWeight 仍然正常。

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

我不明白我在这里缺少什么。正如您所看到的,我尝试了几乎所有我可以在这里做的事情,并且 TextBlock 一直没有格式化。

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

As I saw, a lot of people ran into this exact problem but I can't understand why my case is not working and it is starting to drive me crazy.

Context: I have a DataGrid which is to be colored according to the values of each cell. Hence, I have a dynamic style resolving the actual template to be used for each cell. Backgrounds now work accordingly.

New problem: when I have a dark background, I want the font color to be white and the font weight to be bold so the text is correctly readable. And... I can't style it correctly.

I read some Stackoverflow posts about that:

This one fits my problem but doesn't provide me any working solution
This one is also clear and detail but... duh
This is almost the same problem as me but... Solution does not work

Here is what I tried so far:

<!-- 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>

Does not work. Background is green, but text stays in black & not bold.

BTW, the BoldCellStyle is as easy as it can be:

<Style x:Key="BoldCellStyle" TargetType="{x:Type TextBlock}">
    <Setter Property="FontWeight" Value="Bold"/>
    <Setter Property="Foreground" Value="White" />
</Style>

Okay. Second try (which is a real stupid one but well...)

<!-- 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>

Doesn't work either.

Then, I tried to play with the ContentPresenter's properties:

<!-- 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>

And... As you can expect, this does not even work.

Intrigued, I used Snoop to browse all the components of my interface.
In the first two cases, Snoop actually shows me that each cell is a Grid with a ContentPresenter containing a TextBlock and the actual Style but... The TextBlock's properties do not apply and FontWeight is still normal.

Last case, even more shocking, I can see that snoop shows me that we actually have a ContentPresenter with the right properties (ie TextElement.FontWeight="Bold"), but the autogenerated TextBlock under is - still - not styled.

I can't get what am I missing here. I tried as you can see almost all I could possibly do here, and the TextBlocks keep being non-formatted.

Any idea here? Thanks again!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

淡水深流 2024-12-07 04:13:44

DataGridBoundColumn 派生的 DataGridColumns(除 DataGridTemplateColumn 之外)均具有应用于 ElementStyle 的属性 ElementStyle。 >TextBlock 创建时。例如 DataGridTextColumn 它看起来像这样

static DataGridTextColumn()
{
    ElementStyleProperty.OverrideMetadata(typeof(DataGridTextColumn),
        new FrameworkPropertyMetadata(DefaultElementStyle));
    // ...
}

它覆盖了 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;
    }
}

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

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

<DataGridTextColumn Header="Column 1" ElementStyle="{StaticResource BoldCellStyle}" .../>
<DataGridTextColumn Header="Column 2" ElementStyle="{StaticResource BoldCellStyle}" .../>

The DataGridColumns that derive from DataGridBoundColumn (all except DataGridTemplateColumn) has a property ElementStyle that is applied to the TextBlock when it is created. For e.g. DataGridTextColumn It looks like this

static DataGridTextColumn()
{
    ElementStyleProperty.OverrideMetadata(typeof(DataGridTextColumn),
        new FrameworkPropertyMetadata(DefaultElementStyle));
    // ...
}

It overrides the metadata for ElementStyle and provides a new default value, DefaultElementStyle, which basically just sets the default margin for the 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;
    }
}

This style is set in code everytime a new DataGridCell is created with element.Style = style; and this is overriding the Style you are trying to set, even if you try to set it implicitly.

As far as I know, you'll have to repeat this for your columns

<DataGridTextColumn Header="Column 1" ElementStyle="{StaticResource BoldCellStyle}" .../>
<DataGridTextColumn Header="Column 2" ElementStyle="{StaticResource BoldCellStyle}" .../>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文