Edit: I guess the question wasn't stated very clearly. It actually composes of 4 separate ones:
TextBlock
get its default color, if the client app doesn't provide any style, either programmatically or through xaml? Label
get its default color?TextBlock
get its default font size and font family, if the client app doesn't provide any style, either programmatically or through xaml?Label
get its default font size and font family?BTW, the questions are not about how to change or define styles for the color/font size/font family of a TextBlock
or a Label
, although they are somehow related. I think I already knew the answer for #2, that is a Label
gets its color from SystemColors.ControlTextBrushKey and by overriding ConrolTextBrushKey
like so:
<SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="Red"/>
You would be able to "globally" change color for Label
s. After some research, I guess I also find the answer for #1: A TextBlock
inherits the its foreground color from its containing Window
, which by default gets its Foreground
color from SystemColors.WindowTextBrushKey. By defining a color for the WindowTextBrush like so:
<Window.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.WindowTextBrushKey}"
Color="Yellow"/>
</Window.Resources>
You would be able to change the "foreground" color for the TextBlock
s inside the Window
.
Question #3 and #4 remain puzzles for me, but I am assuming they have to do with the 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 Label
in the theme (for example "aero.normalcolor.xaml") that comes with Windows, you can find
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
Which sets the color for a Label
. But there is no where the FontSize
property 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:
<Style x:Key="{x:Type TextBlock}"
TargetType="{x:Type TextBlock}">
<Setter Property="TextWrapping"
Value="NoWrap"/>
<Setter Property="TextTrimming"
Value="None"/>
</Style>
Where does a Label
or a TextBlock
get the values for its color and font size/family from, if the app doesn't set any, and where are those hooks in WPF?
Edit:
This is a test drive attempting to set the TextBlock
color through SystemColors.ControlTextBrush
(assuming that's where a TextBlock
gets its default color from, which seems to be false):
<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>
In WPF, the default font family for text displayed on controls (like Label and Button) is Segoe UI, with a default size of 12.0 device-independent units.
Most user interface (UI) elements, such as Button and TextBlock, provide a FontFamily property that can be used to specify a font for the text content of a control. You define the font by setting that property with a FontFamily value.
The TextBlock control provides flexible text support for UI scenarios that do not require more than one paragraph of text. It supports a number of properties that enable precise control of presentation, such as FontFamily, FontSize, FontWeight, TextEffects, and TextWrapping.
There is no default color defined in HTML. The "default color" is configured in the browser or by the operating system you are using.
As far as I remember, in most cases classes like TextBlock
, TextBox
and many others take the text color from the TextElement.Foreground
property. 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:
<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.Foreground
to one of the system colors.
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.
UPDATE
The same is true for FontSize
and FontFamily
. They are properties of the TextElement
class 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.
Once again, text color font size and font family are governed by the value of TextElement.Foreground
, TextElement.FontSize
and TextElement.FontFamily
attached dependency properties on a specific visual element.
Some controls, like Label
explicitly set their Foreground
to 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 FontSize
and FontFamily
. You do not need to set them wherever in order for them to work. That's how WPF works.
Supposedly, the values depend on the system theme. I believe they are evaluated during the app startup. Perhaps they are configurable.
UPDATE 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?
It takes it from the inherited value of the TextElement.Foreground
attached 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
How does a Label get its default color?
It takes it from the value of the TextElement.Foreground
attached dependency property. Since its default style sets it to the {DynamicResource {x:Static SystemColors.ControlTextBrushKey}
, it gets bound to the system color.
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?
The same as for its text color. MSDN says that for the default value of the font size is SystemFonts.MessageFontSize which depends on system settings. Font family is determined in similar way from SystemFonts.MessageFontFamily.
Both these default values are passed to the FrameworkPropertyMetadata
constructor upon dependency property registration in the TextElement
static constructor.
Going deeper: SystemFonts.MessageFontFamily
and SystemFonts.MessageFontSize
wrap internal SystemParameters.NonClientMetrics
which in turn are retrieved from the WIN32 native SystemParametersInfo
http://msdn.microsoft.com/en-us/library/ms724947. Thus the WPF is tightly integrated with all Windows UI stuff like themes, fonts, etc.
How does a Label get its default font size and font family?
The same as for TextBlock
. Label
derives from ContentControl
which in turn derives from Control
. Control
class adds itself as an owner of the TextElement.FontFamily
and TextElement.FontSize
properties with the same default values.
See also:
Property Value Inheritance
UPDATE 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.
Overriding default values
Although you cannot change the values of the SystemFonts
properties (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 TextElement
attached properties on the 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 Background
and so on).
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 SystemColors brush key
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Red"/>
According to this: http://msdn.microsoft.com/en-us/library/ms788718.aspx
By default, WPF uses the GlobalUserInterface.composite font in your Windows\Fonts directory.
And according to this: 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.
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).aspx for the style, which says:
The requested font style, which is a FontStyle that is obtained from one of the FontStyles property values. The default is Normal.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With