Стиль DataGridCell правильно - PullRequest
       27

Стиль DataGridCell правильно

4 голосов
/ 18 августа 2011

Это вопрос после моей предыдущей проблемы, вы можете найти его прямо здесь

Итак. Теперь я определил 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 безуспешно

** РЕДАКТИРОВАТЬ: Решение **

Как предложил 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)

Редактировать Похоже, я недостаточно ясен: следующий стиль - это стиль, применяемый к каждому элементу сетки данных через свойство 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 = ноль). Привязка к RelativeSource типа Grid свяжет меня с ... Целым DataGrid докладчиком предметов. Я не уверен, что делать сейчас, поскольку кажется, что из фактического стиля TextBlock я не могу добраться до родительского Grid и, следовательно, не могу определить, какой цвет должен отображаться в соответствии с фоном. Кроме того, я не могу изменить цвет шрифта в моем ControlTemplate, потому что DataGrid хочет Style для каждого столбца, который переопределяет стиль шаблона по умолчанию (см. Мой предыдущий вопрос и его ответ) Итак ... Я снова застрял!

1 Ответ

4 голосов
/ 18 августа 2011

Значение свойства зависимости Приоритет

Это:

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

Не выполняйте запуск внутри шаблона, иначе он станет грязным.

...