【问题标题】:WPF globally styling a TextBlock inside a DataGridWPF 全局样式化 DataGrid 内的 TextBlock
【发布时间】:2012-10-03 18:55:29
【问题描述】:

我遇到了一个非常奇怪的问题。我正在尝试将全局样式应用于DataGrid 中的多个控件。他们中的大多数人完全按照我的期望工作。但是,TextBlock 的样式永远不会被应用。 ComboBoxTextBoxLabel 和其他几个的样式都被应用到各自的控件,但不是 TextBlock。我已经尽可能地简化了代码,问题仍然存在。我在下面提供了代码示例。

我需要将样式应用于TextBlock,我不想手动将其应用于TextBlock

<DataGrid ItemsSource="{Binding Data}" AutoGenerateColumns="False">
    <DataGrid.Resources>
        <Style TargetType="TextBlock">
            <Setter Property="ANY_TEXTBLOCK_PROPERTY" Value="VALUE" />
        </Style>
    </DataGrid.Resources>
    <DataGrid.Columns>
        <DataGridTemplateColumn Header="Test">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="Globably Applied" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

更多信息:

  • TextBlockTextBoxComboBox 等)以外的任何控件的全局样式都可以正常工作。
  • DataTemplate 中定义全局样式将正常工作。
  • 使用x:Key 直接将样式分配给TextBlock 即可。
  • 使用TextElement.PROPERTYDataGridCell 的全局样式将应用于TextBlock

虽然其中一些会将样式应用于TextBlock,但它们也有自己的问题。在DataGridColumn 中的某处直接指定样式或定义样式将意味着我必须多次应用该样式。在DataGridCell 上使用TextElement.PROPERTY 将把样式应用于不仅仅是TextBlock 控件,并且会限制您可以设置的属性数量。

【问题讨论】:

  • 只是为了了解发生了什么...如果将样式移动到 TextBlock 内,会发生什么?
  • 该样式是否适用于不在 CellTemplate 中的常规文本块?
  • 如果样式在DataTemplate 中定义,则应用该样式。如果直接应用于TextBlock,则应用该样式。如果TextBlock 不在DataGrid 内,则应用该样式。
  • 有趣,会不会是一种应用于 datagrid 的样式,间接改变了 TextBlock 的样式?是否有应用于 Datagrid 的样式?
  • 当您使用 WPF 应用程序检查工具(如我的 Snoop)时,TextBlock 没有应用样式。

标签: wpf c#-4.0 wpfdatagrid


【解决方案1】:

因此,通过更多的挖掘和一点点运气,我发现 WPF 不会在模板中应用隐式样式,除非 TargetType 派生自 Control。由于TextBlock 不是从Control 派生的,因此不应用其样式。因此,您要么必须手动将样式应用于每个非Control,要么在模板中定义隐式样式。

下面的 MSDN 博客文章非常详细地解释了它。

https://docs.microsoft.com/en-us/archive/blogs/wpfsdk/implicit-styles-templates-controls-and-frameworkelements

【讨论】:

  • 我知道已经 3 年了,但也许你还记得这个问题。在我发布我自己的问题之前,我想我会先问你,因为这是一个非常具体的问题,从它的外观来看,你对此有更好的把握。我有相同/相似的问题。我想将一种样式全局应用于数据网格单元格中的所有文本块,这种样式会将每个文本块的工具提示属性设置/绑定到它自己的文本。您最终使用了什么解决方案/解决方法?
【解决方案2】:

不幸的是,正如 BrianP 所说,WPF 不能那样工作。但是,可以按如下方式设置单元格样式的 TextElement 属性:

<DataGrid ItemsSource="{Binding Data}" AutoGenerateColumns="False" DockPanel.Dock="Top">
    <DataGrid.CellStyle>
        <Style TargetType="DataGridCell">
            <Setter Property="TextElement.Foreground" Value="Green" />
        </Style>
    </DataGrid.CellStyle>
    <DataGrid.Columns>
        <DataGridTemplateColumn Header="Test">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="not globably applied" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

【讨论】:

  • 我正在尝试将样式应用于全局 DataGrid 中的控件,如果有多个带有 TextBlock 的列,您的解决方案仍然需要我多次应用样式
  • 我已经在我的问题中提到了这一点。您的解决方案的问题在于,它将不仅仅应用于TextBlock 控件。但是,这是我能找到的唯一解决方法,可以将样式全局应用于DataGrid 中的TextBlock 控件。 +1
  • 此外,此解决方案将为您提供一组有限的属性,您可以在 TextBlock 上设置这些属性,而不是实际使用 TargetTypeTextBlock 的样式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多