对ContentPresenter中自动生成的文本框进行样式化 [英] Styling a Textblock autogenerated in a ContentPresenter

查看:1051
本文介绍了对ContentPresenter中自动生成的文本框进行样式化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

正如我所看到的,很多人遇到了这个确切的问题,但我不明白为什么我的案子不工作,它开始让我疯狂。



上下文:我有一个 DataGrid ,它将根据每个单元格的值进行着色。因此,我有一个动态样式来解析每个单元格要使用的实际模板。背景现在可以相应地工作。



新问题:当我有一个黑暗的背景,我想要字体颜色为白色,字体重量为粗体,所以文本是正确的可读的而且...我无法正确风格。



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



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



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

 <! - 绿色模板 - > 
< ControlTemplate x:Key =GreenTargetType ={x:Type tk:DataGridCell}>
< Grid Background =Green>
< ContentPresenter
Horizo​​ntalAlignment =Center
VerticalAlignment =Center>
< ContentPresenter.Resources>
< Style BasedOn ={StaticResource BoldCellStyle}TargetType ={x:Type TextBlock}/>
< /ContentPresenter.Resources>
< / ContentPresenter>
< / Grid>
< / ControlTemplate>

无效。背景是绿色的,但文字保持黑白不大胆。



BTW,BoldCellStyle很简单:

 < Style x:Key =BoldCellStyleTargetType ={x:Type TextBlock}> 
< Setter Property =FontWeightValue =Bold/>
< Setter Property =ForegroundValue =White/>
< / Style>

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

 <! - 绿色模板 - > 
< ControlTemplate x:Key =GreenTargetType ={x:Type tk:DataGridCell}>
< Grid Background =Green>
< ContentPresenter
Horizo​​ntalAlignment =Center
VerticalAlignment =Center>
< ContentPresenter.Resources>
< Style x:Key =BoldCellStyleTargetType ={x:Type TextBlock}>
< Setter Property =FontWeightValue =Bold/>
< Setter Property =ForegroundValue =White/>
< / Style>

< /ContentPresenter.Resources>
< / ContentPresenter>
< / Grid>
< / ControlTemplate>

无效。



然后,我试图玩 ContentPresenter 的属性:

  <! - 绿色模板 - > 
< ControlTemplate x:Key =GreenTargetType ={x:Type tk:DataGridCell}>
< Grid Background =Green>
< ContentPresenter TextElement.FontWeight =BoldTextElement.Foreground =WhiteTextBlock.Foreground =White
Horizo​​ntalAlignment =Center
VerticalAlignment =Center/>
< / Grid>
< / ControlTemplate>

而且...正如你所料,这甚至不起作用。



有趣的是,我使用Snoop浏览我的界面的所有组件。
在前两种情况下,Snoop实际上显示每个单元格是一个 Grid ,其中包含一个 ContentPresenter TextBlock 和实际样式,但... TextBlock 的属性不适用, FontWeight 仍然正常。



最后一种情况,更令人震惊的是,我可以看到这个snoop显示我,我们实际上有一个 ContentPresenter 与正确的属性(即 TextElement.FontWeight =Bold ),但是自动生成的 TextBlock 下是 - 仍然 - 没有样式。



我不能得到我是什么在这里失踪我试过,几乎可以看到我可以在这里做的,而 TextBlock 保持不格式化。



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

解决方案

来自<$ c $的 DataGridColumns c> DataGridBoundColumn (除)具有应用于该元素的属性 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));
//使用与TextBox相同的边距,为插入符提供空格
style.Setters.Add(新的Setter(TextBlock.MarginProperty,新的Thickness(2.0,0.0,2.0,0.0))) ;
style.Seal();
_defaultElementStyle = style;
}
return _defaultElementStyle;
}
}

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



据我所知,你必须重复这个列你的列

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


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!

解决方案

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}" .../>

这篇关于对ContentPresenter中自动生成的文本框进行样式化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆