如何在 WPF 应用程序中设置 TextBlock 和标签的默认颜色、字体系列和字体大小?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8479259/
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-08 23:12:31  来源:igfitidea点击:

How do the default color, font family and font size for a TextBlock and Label get set in an WPF app?

wpfwindowsthemeslabeltextblock

提问by mobileTofu

Edit: I guess the question wasn't stated very clearly. It actually composes of 4 separate ones:

编辑:我想这个问题没有说得很清楚。它实际上由 4 个独立的组成:

  1. How does a TextBlockget its default color, if the client app doesn't provide any style, either programmatically or through xaml?
  2. How does a Labelget its default color?
  3. How does a TextBlockget its default font size and font family, if the client app doesn't provide any style, either programmatically or through xaml?
  4. How does a Labelget its default font size and font family?
  1. TextBlock如果客户端应用程序不以编程方式或通过 xaml 提供任何样式,如何获取其默认颜色?
  2. a 如何Label获得它的默认颜色?
  3. TextBlock如果客户端应用程序不以编程方式或通过 xaml 提供任何样式,如何获取其默认字体大小和字体系列?
  4. a 如何Label获得其默认字体大小和字体系列?

BTW, the questions are not about how to changeor define styles for the color/font size/font family of a TextBlockor a Label, although they are somehow related. I think I already knew the answer for #2, that is a Labelgets its color from SystemColors.ControlTextBrushKeyand by overriding ConrolTextBrushKeylike so:

顺便说一句,问题不是关于如何更改或定义 aTextBlock或 a的颜色/字体大小/字体系列的样式Label,尽管它们有某种关联。我想我已经知道 #2 的答案了,那就是LabelSystemColors.ControlTextBrushKey获取它的颜色,然后ConrolTextBrushKey像这样覆盖:

<SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="Red"/>

You would be able to "globally" change color for Labels. After some research, I guess I also find the answer for #1: A TextBlockinherits the its foreground color from its containing Window, which by default gets its Foregroundcolor from SystemColors.WindowTextBrushKey. By defining a color for the WindowTextBrush like so:

您将能够“全局”更改Labels 的颜色。经过一些研究,我想我也找到了 #1 的答案: ATextBlock从它的 contains 继承其前景色Window,默认情况下ForegroundSystemColors.WindowTextBrushKey获取它的颜色。通过为 WindowTextBrush 定义颜色,如下所示:

<Window.Resources>
    <SolidColorBrush x:Key="{x:Static SystemColors.WindowTextBrushKey}" 
                     Color="Yellow"/>
</Window.Resources>

You would be able to change the "foreground" color for the TextBlocks inside the Window.

您将能够更改 .s 文件中TextBlocks的“前景”颜色Window

Question #3 and #4 remain puzzles for me, but I am assuming they have to do with the SystemFonts.

问题 #3 和 #4 对我来说仍然是个难题,但我假设它们与SystemFonts 有关

Hope this makes sense. I really like to know the answers as they have been bothering me for a while. Many thanks!

希望这是有道理的。我真的很想知道答案,因为它们已经困扰我一段时间了。非常感谢!

Below is the original post:

以下是原帖:



If you look into the style for a Labelin the theme (for example "aero.normalcolor.xaml") that comes with Windows, you can find

如果您查看LabelWindows 附带的主题中的样式(例如“aero.normalcolor.xaml”),您可以找到

<Setter Property="Foreground" 
        Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>

Which sets the color for a Label. But there is no where the FontSizeproperty is specified in the style, which I assume has something to do with the SystemFonts. For a TextBlock, it looks even more mysterious as the style for it in "aero.normalcolor.xaml" has only 4 lines:

它为 a 设置颜色Label。但是FontSize在样式中没有指定属性的位置,我认为这与SystemFonts 有关。对于 a TextBlock,它看起来更加神秘,因为它在“aero.normalcolor.xaml”中的样式只有 4 行:

<Style x:Key="{x:Type TextBlock}"
                 TargetType="{x:Type TextBlock}">
        <Setter Property="TextWrapping"
                        Value="NoWrap"/>
        <Setter Property="TextTrimming"
                        Value="None"/>
    </Style>

Where does a Labelor a TextBlockget the values for its color and font size/family from, if the app doesn't set any, and where are those hooks in WPF?

如果应用程序未设置任何值,aLabel或 aTextBlock从哪里获取其颜色和字体大小/系列的值,以及 WPF 中的那些钩子在哪里?

Edit:

编辑:

This is a test drive attempting to set the TextBlockcolor through SystemColors.ControlTextBrush(assuming that's where a TextBlockgets its default color from, which seems to be false):

这是一个尝试通过设置TextBlock颜色的测试驱动器SystemColors.ControlTextBrush(假设这是从那里TextBlock获取默认颜色的地方,这似乎是错误的):

<Window x:Class="TestFontColor.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<StackPanel>
    <StackPanel.Resources>
        <SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="Red"/>
    </StackPanel.Resources>
    <Button Content="This is red."/>
    <Label Content="This is blue.">
        <Label.Resources>
            <SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="Blue"/>
        </Label.Resources>
    </Label>
    <TextBlock Text="TextBlock: This is still black."/>
</StackPanel>

回答by Pavel Gatilov

As far as I remember, in most cases classes like TextBlock, TextBoxand many others take the text color from the TextElement.Foregroundproperty. The property value is inherited throughout the visual tree, i.e. you may set it on the root element and have most of the text change its color. For example:

至于我记得,在大多数情况下类一样TextBlockTextBox和其他许多人采取从文本的颜色TextElement.Foreground属性。属性值在整个可视化树中继承,即您可以在根元素上设置它并让大部分文本更改其颜色。例如:

<Grid TextElement.Foreground="Red">
  <TextBlock Text="test"/>
</Grid>

In fact, the same is true even for labels: the setter in their default style simply sets the TextElement.Foregroundto one of the system colors.

事实上,即使对于标签也是如此:默认样式的 setter 只是将 设置TextElement.Foreground为系统颜色之一。

However, this is true only for the default state of controls. Altered states, like highlighting, are not inherited, but rather taken from the system colors, as Rachel has written.

但是,这仅适用于控件的默认状态。改变的状态,如突出显示,不是继承的,而是从系统颜色中获取的,正如 Rachel 所写的。

UPDATE

更新

The same is true for FontSizeand FontFamily. They are properties of the TextElementclass that have attached property usage. They inherit their values. Once you set a value on a visual tree item, all its children will get the same value. Unless they override it either by an explicit property assignment, or by style and so on.

FontSize和也是如此FontFamily。它们是TextElement具有附加属性用法的类的属性。他们继承了他们的价值观。在可视化树项上设置值后,其所有子项都将获得相同的值。除非他们通过显式属性分配或样式等覆盖它。

Once again, text color font size and font family are governed by the value of TextElement.Foreground, TextElement.FontSizeand TextElement.FontFamilyattached dependency properties on a specific visual element.

再一次,文本颜色字体大小和字体系列由 的值控制TextElement.ForegroundTextElement.FontSizeTextElement.FontFamily附加在特定视觉元素上的依赖属性。

Some controls, like Labelexplicitly set their Foregroundto some brush. It happens so that the brush is one of the SystemColors. But it doesn't have to be true for all controls. Others (TextBlock, TextBox, etc.) don't override the property value and just use some default settings evaluated on startup. The same happens to FontSizeand FontFamily. You do not need to set them wherever in order for them to work. That's how WPF works.

一些控件,比如Label明确地将它们设置Foreground为一些画笔。碰巧的是,画笔是SystemColors. 但并非所有控件都必须如此。其他(TextBlockTextBox等)不会覆盖属性值,而只是使用在启动时评估的一些默认设置。FontSize和也会发生同样的情况FontFamily您不需要将它们设置在任何地方以使它们工作。这就是 WPF 的工作原理。

Supposedly, the values depend on the system theme. I believe they are evaluated during the app startup. Perhaps they are configurable.

据说,这些值取决于系统主题。我相信它们是在应用程序启动期间进行评估的。也许它们是可配置的。

UPDATE 2

更新 2

Answers to your new questions:

回答您的新问题:

How does a TextBlock get its default color, if the client app doesn't provide any style, either programmatically or through xaml?

如果客户端应用程序不以编程方式或通过 xaml 提供任何样式,TextBlock 如何获得其默认颜色?

It takes it from the inherited value of the TextElement.Foregroundattached dependency property. By default it is inherited from the root visual element, which in turn is simply set to the default value of the dependency property (Brushes.Black). See also

它从TextElement.Foreground附加的依赖属性的继承值中获取。默认情况下,它是从根视觉元素继承的,而根视觉元素又简单地设置为依赖属性 ( Brushes.Black)的默认值。也可以看看

How does a Label get its default color?

标签如何获得默认颜色?

It takes it from the value of the TextElement.Foregroundattached dependency property. Since its default style sets it to the {DynamicResource {x:Static SystemColors.ControlTextBrushKey}, it gets bound to the system color.

它从TextElement.Foreground附加的依赖属性的值中获取。由于其默认样式将其设置为{DynamicResource {x:Static SystemColors.ControlTextBrushKey},因此它会绑定到系统颜色。

How does a TextBlock get its default font size and font family, if the client app doesn't provide any style, either programmatically or through xaml?

如果客户端应用程序不以编程方式或通过 xaml 提供任何样式,TextBlock 如何获得其默认字体大小和字体系列?

The same as for its text color. MSDN says that for the default value of the font size is SystemFonts.MessageFontSizewhich depends on system settings. Font family is determined in similar way from SystemFonts.MessageFontFamily. Both these default values are passed to the FrameworkPropertyMetadataconstructor upon dependency property registration in the TextElementstatic constructor.

与它的文本颜色相同。MSDN 说字体大小的默认值是SystemFonts.MessageFontSize,这取决于系统设置。字体系列的确定方式与SystemFonts.MessageFontFamily类似。FrameworkPropertyMetadataTextElement静态构造函数中注册依赖属性时,这两个默认值都会传递给构造函数。

Going deeper: SystemFonts.MessageFontFamilyand SystemFonts.MessageFontSizewrap internal SystemParameters.NonClientMetricswhich in turn are retrieved from the WIN32 native SystemParametersInfohttp://msdn.microsoft.com/en-us/library/ms724947. Thus the WPF is tightly integrated with all Windows UI stuff like themes, fonts, etc.

更深入:SystemFonts.MessageFontFamilySystemFonts.MessageFontSize包装内部SystemParameters.NonClientMetrics,反过来又从 WIN32 本机SystemParametersInfohttp://msdn.microsoft.com/en-us/library/ms724947检索。因此,WPF 与所有 Windows UI 内容(如主题、字体等)紧密集成。

How does a Label get its default font size and font family?

标签如何获得其默认字体大小和字体系列?

The same as for TextBlock. Labelderives from ContentControlwhich in turn derives from Control. Controlclass adds itself as an owner of the TextElement.FontFamilyand TextElement.FontSizeproperties with the same default values.

与 相同TextBlockLabel派生自ContentControl又派生自ControlControl类将自身添加为具有相同默认值的TextElement.FontFamilyTextElement.FontSize属性的所有者。

See also:

也可以看看:

Property Value Inheritance

属性值继承

UPDATE 3

更新 3

You should understand the main idea: the values are inherited. It means they might be inherited from anywhere, from any control. You can tell exactly which one it is inherited from only for a certain logical tree structure. You change it a bit - and the colors change. Someone sets a property's value explicitly - and all children will inherit the value. Therefore your questions make little practival sense. But they are still interesting from the perspective of undestanding the WPF.

您应该理解主要思想:值是继承的。这意味着它们可能从任何地方、任何控件继承。您可以准确地分辨出它是从哪个逻辑树结构继承而来的。你稍微改变一下 - 颜色也会改变。有人明确地设置了一个属性的值——所有的孩子都会继承这个值。因此,您的问题几乎没有实际意义。但是从理解 WPF 的角度来看,它们仍然很有趣。

Overriding default values

覆盖默认值

Although you cannot change the values of the SystemFontsproperties (they are read-only), you don't have to. To change the font size and family for the whole window, simply assign the desired values to the TextElementattached properties on the Window:

尽管您不能更改SystemFonts属性的值(它们是只读的),但您不必这样做。要更改整个窗口的字体大小和系列,只需将所需的值分配给 上的TextElement附加属性Window

<Window TextElement.FontSize="20" TextElement.FontFamily="Century Gothic">
  ..
</Window>

and all controls that do not explicitly override the inheritance will receive the settings. For those that do override - you'll have to override their default styles or even throw them away if they hard-code the values.

并且所有未显式覆盖继承的控件都将接收设置。对于那些确实覆盖的人 - 如果他们对值进行了硬编码,您将不得不覆盖他们的默认样式,甚至将它们丢弃。

The same approach works for TextElement.Foreground(and Backgroundand so on).

相同的方法适用于TextElement.ForegroundBackground等等)。

回答by Rachel

The default colors are pulled from the operating system's settings.

默认颜色是从操作系统的设置中提取的。

You can overwrite them by creating a brush which has the a key that references a SystemColorsbrush key

您可以通过创建一个具有引用SystemColors画笔键的键的画笔来覆盖它们

<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Red"/>

回答by Verifex

According to this: http://msdn.microsoft.com/en-us/library/ms788718.aspx

根据这个:http: //msdn.microsoft.com/en-us/library/ms788718.aspx

By default, WPF uses the GlobalUserInterface.composite font in your Windows\Fonts directory.

默认情况下,WPF 使用 Windows\Fonts 目录中的 GlobalUserInterface.composite 字体。

And according to this: http://msdn.microsoft.com/en-us/library/system.windows.controls.textblock.fontsize(v=vs.95).aspx

根据这个:http: //msdn.microsoft.com/en-us/library/system.windows.controls.textblock.fontsize(v=vs.95).aspx

A non-negative value that specifies the font size, measured in pixels. The default is 11.

指定字体大小的非负值,以像素为单位。默认值为 11。

In addition, you can find many of the other default values stored in various places in the MSDN site: http://msdn.microsoft.com/en-us/library/system.windows.controls.textblock.fontstyle(v=VS.95).aspxfor the style, which says:

此外,您可以在 MSDN 站点的不同位置找到许多其他默认值:http: //msdn.microsoft.com/en-us/library/system.windows.controls.textblock.fontstyle(v= VS .95).aspx的样式,它说:

The requested font style, which is a FontStyle that is obtained from one of the FontStyles property values. The default is Normal.

请求的字体样式,它是从 FontStyles 属性值之一获取的 FontStyle。默认为正常。