首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >正确设计DataGridCell样式

正确设计DataGridCell样式
EN

Stack Overflow用户
提问于 2011-08-18 11:58:24
回答 1查看 16.7K关注 0票数 5

这是继我之前的问题,你可以在那里找到它之后的一个问题

所以。现在,我为每一列定义了一个带有特定ElementStyleElementStyle(它只是用粗体和白色定义了TextBlock内部--稍后将讨论这个问题)。

所以现在我有两个问题

第一个问题(已解决)

当我碰巧将背景设置为我的单元格时,它会覆盖默认样式,并且当单元格被高亮显示时,背景保持不变。

一种风格的一个例子:

代码语言:javascript
复制
<!-- 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的背景设置为绿色。因此,我尝试了这样做:

代码语言:javascript
复制
<!-- 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证实了这一点.)

第三次尝试:

代码语言:javascript
复制
<!-- 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>

还有..。不显示背景(保持透明)

因此,我认为我在这里工作的方式是错误的,我想知道我应该做什么来定义“未选定的”模板。我想说的是,我可能需要将样式BasedOn定义为“经典”风格,但是,我如何才能做到呢?我试图添加TemplateBindings,但没有成功

编辑:解决方案**

正如his在他的回答中所指出的,问题来自于DependencyProperty的优先性,以下是解决办法:

代码语言:javascript
复制
<!-- 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应用于数据存储的每一项的样式。下面是处理以下代码的代码:

代码语言:javascript
复制
    void VolatilityDataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
    {
        DataGridTextColumn column = e.Column as DataGridTextColumn;
        column.ElementStyle = s_boldCellStyle;
        // Other stuff here...
    }

以下是我所做的:

代码语言:javascript
复制
<!-- 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 = null)。绑定到RelativeSource类型的Grid将使我绑定到.整个DataGrid项目演示者。我现在不知道该做什么,因为从实际的TextBlock样式来看,我无法到达父Grid,因此无法根据背景来解析应该显示的颜色。另外,我不能在我的ControlTemplate中更改字体颜色,因为DataGrid需要为每一列设置一个Style,这会在默认情况下重写模板的样式,因此.我又卡住了!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-08-18 12:12:07

依赖属性值优先

这是:

代码语言:javascript
复制
<Grid Background="LightGreen">
    <Grid.Resources>
        <Style TargetType="{x:Type Grid}">
            <!-- Trigger Stuff -->
        </Style>
    </Grid.Resources>
    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>

需要:

代码语言:javascript
复制
<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示例:

代码语言:javascript
复制
<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>
代码语言:javascript
复制
<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连接属性。例如:

代码语言:javascript
复制
<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>

不要在模板内部触发,否则会变得混乱。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7107044

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档