为什么我的风格没有被应用? [英] Why doesn't my style get applied?

查看:73
本文介绍了为什么我的风格没有被应用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题与这篇文章中的问题相同.但是,由于这篇旧文章四年来一直没有答案,所以我想也许有一些新的见解可以解释为什么它不像预期的那样起作用.

my question is the same as in this post. But since this old post is without an answer for four years I thought maybe there are new insights on why this is not working like it's supposed to be.

在我的窗口资源中,我为TextBlock定义了一种简单的样式.样式没有x:Key属性,因此应该将其应用于窗口中所有不具有自己样式的TextBlock控件.

In my window resources I define a simple style for a TextBlock. The style doesn't have a x:Key attribute, so it's supposed to be applied to all TextBlock controls within my window which doesn't have a style of their own.

然后我创建一个ListView,将GridView定义为其视图. ListView定义了四个列,两个列定义为包含TextBlock的显式CellTemplate,而两个列定义为不包含CellTemplate的显式.

Then I create a ListView with a GridView defined as its view. The ListView has four colums defined, two columns are defined with an explicit CellTemplate containing a TextBlock and two columns are defined without an explicit CellTemplate.

这是我完整的XAML代码(问题在代码下方):

Here's my complete XAML-code (the question follows under the code):

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfApplication1"
    mc:Ignorable="d"
    Title="MainWindow" SizeToContent="WidthAndHeight">

<Window.Resources>
    <Style TargetType="{x:Type TextBlock}">
        <Setter Property="HorizontalAlignment" Value="Stretch" />
        <Setter Property="TextTrimming" Value="CharacterEllipsis" />
        <Setter Property="Background" Value="Aqua" />
    </Style>

    <Style x:Key="ListViewItemStyle" TargetType="ListViewItem">
        <Setter Property="HorizontalContentAlignment" Value="Stretch" />
    </Style>
</Window.Resources>

<ListView ItemContainerStyle="{StaticResource ListViewItemStyle}">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Bottom" Width="50" DisplayMemberBinding="{Binding Bottom}" />
            <GridViewColumn Header="Left" Width="50">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Left}" TextAlignment="Center" />
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
            <GridViewColumn Header="Right" Width="50">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Right}" TextAlignment="Right" />
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
            <GridViewColumn Header="Top" Width="50" DisplayMemberBinding="{Binding Top}" />
        </GridView>
    </ListView.View>
    <ListView.Items>
        <Thickness>1,2,3,4</Thickness>
        <Thickness>5,6,7,8</Thickness>
        <Thickness>9,10</Thickness>
    </ListView.Items>
</ListView>
</Window>

如果运行此代码,我会看到应该应用于所有TextBlock控件的TextBlock样式仅在没有显式CellTemplate的列中处于活动状态.

If I run this code, I can see, that my TextBlock style, that is supposed to be applied to all TextBlock controls, is only active in the columns that don't have an explicit CellTemplate.

那是为什么?

当我检查视觉树时,我看到,工作列(没有 CellTemplate的工作列)是由TextBlock组成的,并且将我的样式应用于该列,不起作用(带有CellTemplate)是由内部带有TextBlockContentPresenter组成的,但是TextBlock根本没有样式.

When I inspect the visual tree I can see, that the working columns (the ones without a CellTemplate) are made of a TextBlock with my style applied to it, while the columns, which don't work (the ones with a CellTemplate) are made of a ContentPresenter with a TextBlock inside, but the TextBlock has no style at all.

推荐答案

此行为实际上是设计使然. 此链接描述了正在发生的事情.早在2006年10月,Microsoft Connect上也有一个错误报告.遗憾的是,给定链接中指向该错误报告的原始链接不再起作用.

This behavior is actually by design. This link describes what is going on. There was also a bug report on Microsoft Connect back in October 2006. Unfortunately the original link to the bug report in the given link does not work anymore.

在这里,我列举了Connect的错误报告的答案,以防将来给定的链接断开.

Here I'm reciting the answer to the bug report from Connect in case the given link goes down in future.

此行为是按设计",这就是原因.模板被视为封装边界.这些模板产生的元素都在此边界之内.对于具有匹配TargetType的样式的查找将在此边界处停止.因此,通过模板生成的repro中的TextBlock不会拾取有问题的样式.而在模板外部定义的TextBlock可以. 解决此问题的一种方法是为样式指定一个明确的名称,并通过此名称在模板中的TextBlock上引用该样式.

This behavior is 'By Design' and this is why. Templates are viewed as an encapsulation boundary. Elements produced by these templates fall within this boundary. And lookup for a style with a matching TargetType stops at this boundary. Hence the TextBlock in the repro which is produced through a template does not pick up the Style in question. Whereas the TextBlock defined outside the template does. One way to work around this problem is to give an explicit name to the Style and reference the style by this name on the TextBlock within the template.

您看到他们已经为您的问题提供了解决方法.他们声明您应该在Window.Resources中为您的TextBlock样式命名,并在模板中引用该样式.

You see that they already provided a workaround for your issue. They state that you should give your TextBlock style in the Window.Resources a name and reference the style in the template.

我认为这不是您真正想要的,因为在那种情况下,样式不会自动应用于所有TextBlocks(在DataTemplate之外).因此,不必在Windows.Resources中为样式指定一个明确的名称,而是可以在引用样式时在BasedOn属性中进行一些操作.您无需指定样式的名称,而是指定类似的类型.

I think this is not what you actually want, because in that case the style doesn't automatically get applied to all TextBlocks (outside the DataTemplate). For that reason, instead of giving the style in Windows.Resources an explicit name, you can do a little trick in your BasedOn property when referencing the style. Instead of specifying the name of the style, you specify the type like this.

<GridViewColumn Header="Left" Width="50">
    <GridViewColumn.CellTemplate>
        <DataTemplate>
            <DataTemplate.Resources>
                <Style TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}" />
            </DataTemplate.Resources>
            <TextBlock Text="{Binding Left}" TextAlignment="Center" />
        </DataTemplate>
    </GridViewColumn.CellTemplate>
</GridViewColumn>

使用这种方法,您仍然具有不为样式指定名称的优点,并且该样式将应用于所有TextBlock.

With that approach, you still have the advantage of not specifying a name for your style and the style gets applied to all TextBlocks.

作为参考,整个Window XAML看起来像这样.现在,GridView中的所有列都具有相同的样式.

For reference, the whole Window XAML looks like this. Now, all columns in the GridView have the same style.

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfApplication1"
    mc:Ignorable="d"
    Title="MainWindow" SizeToContent="WidthAndHeight">

    <Window.Resources>
        <Style TargetType="{x:Type TextBlock}">
            <Setter Property="HorizontalAlignment" Value="Stretch" />
            <Setter Property="TextTrimming" Value="CharacterEllipsis" />
            <Setter Property="Background" Value="Aqua" />
        </Style>

        <Style x:Key="ListViewItemStyle" TargetType="ListViewItem">
            <Setter Property="HorizontalContentAlignment" Value="Stretch" />
        </Style>
    </Window.Resources>

    <ListView ItemContainerStyle="{StaticResource ListViewItemStyle}">
        <ListView.View>
            <GridView>
                <GridViewColumn Header="Bottom" Width="50" DisplayMemberBinding="{Binding Bottom}" />
                <GridViewColumn Header="Left" Width="50">
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <DataTemplate.Resources>
                                <Style TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}" />
                            </DataTemplate.Resources>
                            <TextBlock Text="{Binding Left}" TextAlignment="Center" />
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
                <GridViewColumn Header="Right" Width="50">
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <DataTemplate.Resources>
                                <Style TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}" />
                            </DataTemplate.Resources>
                            <TextBlock Text="{Binding Right}" TextAlignment="Right" />
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
                <GridViewColumn Header="Top" Width="50" DisplayMemberBinding="{Binding Top}" />
            </GridView>
        </ListView.View>
        <ListView.Items>
            <Thickness>1,2,3,4</Thickness>
            <Thickness>5,6,7,8</Thickness>
            <Thickness>9,10</Thickness>
        </ListView.Items>
    </ListView>
</Window>

这篇关于为什么我的风格没有被应用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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