Стилизация текстового блока, автоматически сгенерированного в ContentPresenter - PullRequest
5 голосов
/ 17 августа 2011

Как я увидел, многие люди столкнулись с этой проблемой, но я не могу понять, почему мой случай не работает, и он начинает сводить меня с ума.

Контекст: у меня есть 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 s не форматируются.

Есть идеи здесь?Еще раз спасибо!

1 Ответ

2 голосов
/ 17 августа 2011

DataGridColumns, производное от DataGridBoundColumn (все, кроме DataGridTemplateColumn), имеет свойство 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;
    }
}

Этот стиль устанавливается в коде каждый раз, когда новый DataGridCell создается с element.Style = style;, и это переопределяет стиль, который вы пытаетесь установить, даже если вы пытаетесь установить его неявно.

Насколько я знаю, вам придется повторить это для ваших столбцов

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