WPF 在 DataGrid 中全局设置 TextBlock 样式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12714982/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 05:37:58  来源:igfitidea点击:

WPF globally styling a TextBlock inside a DataGrid

wpfc#-4.0wpfdatagrid

提问by Bryan Watts

I am encountering a very weird issue. I am trying to apply global styling to several controls within a DataGrid. Most of them work exactly how I would expect them to. However, the styling for the TextBlocknever gets applied. Styles for ComboBox, TextBox, Label, and several others all are getting applied to their respective controls, but not the TextBlock. I have simplified the code as much as possible and the issue is still present. I have provided the code sample below.

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

I need the style to be applied to the TextBlockand I don't want to have to apply it manually to the 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>

More Information:

更多信息:

  • Global styles for any control other than TextBlock(TextBox, ComboBox, etc.) work properly.
  • Defining the global style inside the DataTemplatewill work properly.
  • Directly assigning the style to the TextBlockusing an x:Keywill work.
  • Global styles for DataGridCellusing TextElement.PROPERTYwill get applied to a TextBlock.
  • 比其他任何控制全局样式TextBlockTextBoxComboBox,等)的正常工作。
  • 在里面定义全局样式DataTemplate会正常工作。
  • 直接将样式分配给TextBlockusingx:Key将起作用。
  • 全球风格的DataGridCell使用TextElement.PROPERTY将得到应用到TextBlock

While some of these will get the style applied to the TextBlock, they have there own issues. Directly assigning the style or defining the style somewhere within a DataGridColumnwill mean that I will have to apply the style more than once. Using the TextElement.PROPERTYon the DataGridCellwill apply the style to more than just TextBlockcontrols and will limit the number of properties that you can set.

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

采纳答案by Bryan Watts

So with a bit more digging and a little luck, I discovered that WPF does not apply implicit styles inside templates unless the TargetTypederives from Control. Since TextBlockdoesn't derive from Control, its style is not applied. So you either have to manually apply the style to every non-Controlor define the implicit style inside the template.

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

The following MSDN blog post explains it in pretty good detail.

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

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

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

回答by F. Erken

Unfortunately, like BrianP said, WPF does not work that way. But, it is possible to set the TextElement properties of the cell style as follows:

不幸的是,就像 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>