Search code examples
wpfxamluser-interfacetextboxfont-family

Setting FontFamily of TextBox applicationwide


I have a big project at hand which involves a large amount of views and usercontrols. Additionaly, I want to set the FontFamily of every element to a certain font.

This works with most of the usercontrols like textBlocks, buttons and labels. Sadly this does not hold for textBoxes. They remain unchanged.

Before I create the whole GUI, I am overriding most of the metadata for elements containing text:

TextElement.FontFamilyProperty.OverrideMetadata(typeof(TextElement), 
    new FrameworkPropertyMetadata(new FontFamily("Calibri")));
TextBlock.FontFamilyProperty.OverrideMetadata(typeof(TextBlock), 
    new FrameworkPropertyMetadata(new FontFamily("Calibri")));

After a bit of searching, I found this article using the same method: http://blog.davidpadbury.com/

It clearly states at the end:

"In the above image you’ll see that we’ve successfully change the font on the text blocks, labels and buttons. Unfortunately the font inside the TextBox remains unchanged, this is due to it receiving it’s FontFamily property from it’s base class Control. Control adds itself as an Owner of the TextElement FontFamilyProperty but specifies it’s own metadata which we are then unable to override."

It also suggests to create a control template, which then sets the fontFamily. Is there another way? I want to set the fontFamily programmatically at the start without using XAML or creating a controlTemplate and using it as a base template for every textBox.

Thanks in advance.


Solution

  • You can declare a Style without the x:Key property and it will apply to all controls of that type:

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

    Alternatively, you can simply set this on the MainWindow definition which will affect most elements:

    <Window TextElement.FontFamily="Calibri" ...>
        ...
    </Window>
    

    Ahhh... I've just noticed your condition of not using xaml... sorry, I should have looked closer the first time.


    UPDATE >>>

    After a little research, it seems that you can do this in code like this:

    Style style = new Style(typeof(TextBlock));
    Setter setter = new Setter();
    setter.Property = TextElement.FontFamilyProperty;
    setter.Value = new FontFamily("Calibri");
    style.Setters.Add(setter);
    Resources.Add(typeof(TextBlock), style);
    

    Unfortunately, you'd have to do other Styles for other types of controls too.


    UPDATE 2 >>>

    I just thought of something... that previous example just set the Style into the local Resources section which would be out of scope for your other modules. You could try setting the Style to the Application.Resources section which has global scope. Try replacing the last line of the code example above to this:

    App.Current.Resources.Add(typeof(TextBlock), style);