80
votes

I want to be able to define a font family for my WPF application. Preferably using a resource dictionary as a theme referenced from App.xaml. I've tried creating a Style as follows:

<Style TargetType="{x:Type Control}">
    <Setter Property="FontFamily" Value="Segoe UI" />            
</Style>

But this doesn't work. Setting the type to TextBlock works for most controls but there are a few controls where this doesn't apply.

I know you can set the font on a window and have all child controls of that window inherit the font. But I think any dialog windows will go back to the default font, which is not exactly what I want.

Any ideas?

6

6 Answers

61
votes

Assuming your Window subclasses don't override DefaultStyleKey, you can simply add it to your Window style, since TextElement.FontFamilyProperty is an inherited property:

<Style TargetType="{x:Type Window}"> 
    <Setter Property="FontFamily" Value="Segoe UI" />             
</Style> 

You also need to add the following to your App constructor after the InitializeComponent call:

FrameworkElement.StyleProperty.OverrideMetadata(typeof(Window), new FrameworkPropertyMetadata
{
    DefaultValue = FindResource(typeof(Window))
});

How it works: After the App object finishes initializing, the Window style specified therein is made the default style for all windows.

28
votes

Most of proposed solutions didn't work for me. My simple solution:

Add this to App.xaml:

<Style TargetType="{x:Type Window}">
    <Setter Property="FontSize"
            Value="14" />
</Style>

Add this in your MainWindow constructor (after InitializeComponent):

Style = (Style)FindResource(typeof(Window));
13
votes

One simple way to do it programmatically:

public MainWindow()
{
    this.FontFamily = new FontFamily("Segoe UI");
}
12
votes

Actually you can get a full XAML solution combining some of the other answers here.

If your main window is called WinMain (the one you load before all others), just add a reference to a style named e.g. WinAll

<Window x:Class="MyNamespace.WinMain"
    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"
    mc:Ignorable="d"
    Title="WinMain" Height="450" Width="800"
    Style="{StaticResource WinAll}">

and then define your style this way

<Style x:Key="WinAll" TargetType="{x:Type Window}">
    <Setter Property="FontFamily"
        Value="Comic Sans MS" />
    <Setter Property="FontSize"
        Value="14" />
</Style>
8
votes

I found this :

TextElement.FontFamilyProperty.OverrideMetadata(
typeof(TextElement),
new FrameworkPropertyMetadata(
    new FontFamily("Comic Sans MS")));

TextBlock.FontFamilyProperty.OverrideMetadata(
typeof(TextBlock),
new FrameworkPropertyMetadata(
    new FontFamily("Comic Sans MS")));
0
votes

Try this simple workaround in the App.xaml (no code behind needed):

<SolidColorBrush x:Key="ForeBrush" Color="Blue" />

<Style x:Key="GenericTextStyle">
    <!-- Generic control forecolor definition -->
    <Setter Property="Control.Foreground" Value="{StaticResource ForeBrush}" />

    <!-- Add a definition for each unworking nested control -->
    <Style.Resources>
        <Style TargetType="{x:Type Label}">
            <Setter Property="Foreground" Value="{StaticResource ForeBrush}" />
        </Style>
    </Style.Resources>
</Style>

Just bind your windows style to this. Works perfectly for me. Only some properties need to be defined in the nested tree. For example the property FontSize can be specify only in the generic section.

I don't know why is necessary to do this trick. It's strange because Label should be derived from Control. Anyone have any idea about it?