为什么我的风格没有被应用?

2024-01-12

我的问题与这个帖子 https://stackoverflow.com/questions/10231095/why-doesnt-my-text-block-style-get-applied。但由于这篇旧文章四年来都没有答案,我想也许对于为什么它没有像预期的那样工作有新的见解。

在我的窗口资源中,我定义了一个简单的样式TextBlock。该样式没有x:Key属性,所以它应该适用于所有TextBlock我的窗口中的控件没有自己的样式。

然后我创建一个ListView with a GridView定义为其视图。这ListView定义了四列,其中两列是用显式定义的CellTemplate含有一个TextBlock并且两列的定义没有明确CellTemplate.

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

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

这是为什么?

当我检查可视化树时,我可以看到工作列(without a CellTemplate)由TextBlock应用了我的风格,而列不起作用(那些with a CellTemplate)由ContentPresenter with a TextBlock里面,但是TextBlock完全没有风格。


这种行为实际上是设计使然。这个链接 http://www.11011.net/archives/000692.html描述正在发生的事情。早在 2006 年 10 月,Microsoft Connect 上就有一个错误报告。不幸的是,给定链接中指向错误报告的原始链接不再有效。

在这里,我将引用 Connect 的错误报告的答案,以防将来给定的链接出现故障。

这种行为是“设计使然”,这就是原因。模板被视为封装边界。这些模板生成的元素落在该边界内。具有匹配 TargetType 的样式的查找将在此边界停止。因此,通过模板生成的重现中的 TextBlock 不会选择有问题的样式。而在模板外部定义的 TextBlock 则可以。 解决此问题的一种方法是为样式指定一个显式名称,并在模板内的 TextBlock 上通过该名称引用样式。

您会看到他们已经为您的问题提供了解决方法。他们说你应该给你TextBlock风格在Window.Resources名称并引用模板中的样式。

我认为这不是您真正想要的,因为在这种情况下,样式不会自动应用于所有 TextBlock(在 DataTemplate 之外)。因此,不要给出样式Windows.Resources一个明确的名字,你可以在你的BasedOn引用样式时的属性。您可以像这样指定类型,而不是指定样式的名称。

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

作为参考,整个 Window XAML 如下所示。现在,所有列GridView有相同的风格。

<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>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么我的风格没有被应用? 的相关文章

  • Android:按钮位于列表视图末尾或屏幕底部

    我的 Android 应用程序要求一个按钮位于列表的底部 这是故意这样做的 因此用户必须滚动整个列表 并且可能会看到更多答案 因此 我将按钮添加为列表视图页脚 这一切都工作正常 但在某些情况下 列表太短 其中只有 3 4 个项目 因此按钮最
  • 如何将图像转换为字节数组[重复]

    这个问题在这里已经有答案了 有人能建议我如何将图像转换为字节数组 反之亦然吗 我正在开发 WPF 应用程序并使用流读取器 将图像更改为字节数组的示例代码 public byte ImageToByteArray System Drawing
  • XAML 图标 - 如何使用?

    我有一些 XAML 格式的矢量图形文件 我想将它们用作 Silverlight 应用程序中的图标 按钮 我更喜欢的方法是使用 Image 控件并将其源属性设置为 xaml 文件 就像我可以使用常规位图图像一样 但这并不那么容易 我尝试将它们
  • 将 winform 树视图转换为 wpf 树视图

    我已经构建了一个在 winforms 中生成树视图的函数 它包括具有递归的子文件夹和文件 现在我想将其转换为 wpf 我不知道如何处理课程 我知道我必须制作自己的自定义类 treenode 它有一个属性 parent 类似于 winform
  • 指定 Xaml 中开始标记和结束标记之间的属性

    考虑以下 Xaml
  • WPF:路由事件还是常规事件?

    在 WPF 中 我们有路由事件 什么时候应该使用这些来代替常规事件 路由事件具有特殊的行为 但如果您在引发事件的元素上处理事件 则该行为在很大程度上是不可见的 如果您使用任何建议的方案 路由事件就会变得强大 在公共根定义公共处理程序 组合您
  • 将 RenderTargetBitmap 转换为 System.Drawing.Image

    我有 3D WPF 视觉对象 我想将其传递到 Excel 单元格 通过剪贴板缓冲区 对于 普通 BMP 图像 它可以工作 但我不知道如何转换RenderTargetBitmap 我的代码如下所示 System Windows Media I
  • 如何更改通用Windows平台应用程序中单击事件上按钮的背景颜色?

    我正在 Windows 10 中开发 UWP 应用程序 并且尝试更改单击事件中按钮的背景颜色 这是我的代码 private void button1 1 Click object sender RoutedEventArgs e if Si
  • Android ListView 复选框选择

    我在这里有一个由两部分组成的问题 1 如何填充我的ListView以便显示字符串 但是当选择项目时 不可见的id值 来自手机联系人的联系人id 是实际使用的值 2 我有一个使用 multipleChoice 模式进行项目选择的 ListVi
  • 从 WPF 窗口中删除图标

    我可以使用 WinApi 从 WPF 窗口中删除窗口图标 但是当我仅运行 WPF 项目的可执行文件时 我会在应用程序窗口中再次获得该图标 如何删除该图标 From WPF教程 http www wpftutorial net RemoveI
  • WPF 位图到图像的转换仅显示黑色图像

    我确实在以 wpf Image 形式显示图像 uEye Cam 时遇到一些问题 显示的 图像全黑 下面是我使用的代码 Get Cam Bitmap Image var cam new uEye Camera cam Init cam Mem
  • 如何覆盖全局样式(没有 x:Key),或者将命名样式应用于所有类型目标控件?

    我声明了一个要应用于项目中所有按钮的样式 该样式位于 ResourceDictionary 中 现在 在某个窗口中 我想继承此样式但添加一个值
  • 将多个 div 与父 div 的底部对齐

    我在父 div 中有多个子 div 使用CSS 是否可以将所有子 div 垂直对齐到父容器的底部 以便显示如下内容 子 div 的高度未知 动态 p Top of page p div div class message Message 4
  • 使用 MVVM 时 XamDataGrid 列可见性不起作用

    我正在尝试在 MVVM 架构中实现 XamDataGrid 列可见性 但它似乎不起作用 我正在执行以下操作 为未绑定字段添加可见性属性
  • WPF RichTextBox 中的只读 Run 元素?

    我可能完全是在想象这一点 但我可以发誓有一种方法可以使 RichTextBox 中的各个 Run 或 Parapgraph 元素成为只读 我还可以发誓 几周前我自己尝试了一种方法 并对结果感到满意 我隐约记得它看起来像这样
  • Wpf ScrollViewer 滚动量

    是否可以更改 WPF ScrollViewer 滚动的量 我只是想知道是否可以更改滚动查看器 以便在使用鼠标滚轮或滚动查看器箭头时可以更改增量滚动量 简短的答案是 如果不编写一些自定义滚动代码 就无法做到这一点 但不要让这吓到你 这并不那么
  • 给 MVVM 中的 View 一些命令

    假设我有一些用户控制权 用户控件有一些子窗口 用户控制用户想要关闭某种类型的子窗口 用户控制代码后面有一个方法 public void CloseChildWindows ChildWindowType type 但我无法调用此方法 因为我
  • 使用 C# 从 UIElement 截取 WPF 屏幕截图 JPG

    我正在尝试从我的 WPF 应用程序的一部分创建 JPG 就像截图一样 只是个人的UIElements 我从这里开始 http www grumpydev com 2009 01 03 take wpf screenshots http ww
  • ListView选择单个项目,wpf

    我有一个列表视图 它的项目源是一个列表 我希望用户只选择一项 当我将列表视图的 SelectionMode 设置为 single 时 用户仍然可以选择多个项目 并且列表视图似乎变得疯狂并选择用户未选择的项目 看起来很奇怪 任何人都知道可能是
  • 获取上下文菜单的控制

    我有一个如下所示的上下文菜单 A 1 2 3 选择 1 2 或 3 后 我需要访问调用上下文菜单的对象 意思是如果这是 textbox1 的上下文菜单 那么我需要访问该对象 我该怎么做 忘了说了 这是一个WPF应用程序 所以我使用 Syst

随机推荐