Click here to Skip to main content
Click here to Skip to main content

Adjusting font and layout for cross-Windows compatibility

, 19 Jul 2007
Rate this:
Please Sign up or sign in to vote.
How to display fonts on Windows Forms according to OS and theme defaults

Screenshot - Immagine4.png

Screenshot - Cattura2.png

Introduction

A noticeable problem .NET developers may have when they design their application is making it appear perfect on any recent Windows platform such as Windows 2000, Windows XP and the current Windows Vista. Before I installed Visual Studio 2005 on a fresh Windows Vista install, I candidly thought that the .NET runtime would have automatically solved the issue. This is true, but only with menus and status bars. If you are looking for compatibility between Windows 2000 and XP platforms, there is actually no problem. The issue is much more tricky if you want perfectly identical application displays on both Windows 2000/XP and Windows Vista. The reason is that Windows Vista:

  • Has a new default font (Segoe UI vs. Tahoma)
  • Has a new default font size (9.25 vs. 8.25)

Of course, designing a number of different versions for any different OS is not, in most cases, an option. My goal was to find an easy way to update my applications in order to display the right font and the right size according to the Windows OS and theme, without having to completely redesign them. The main difficulty is that the new Vista OS fonts have a different size and geometry.

A simple approach

The first idea is obvious: if the user is running Vista, then change to the SegoeUI font family with size 9.25 points for any control. Much better than that is to ask the .NET runtime, which is the default font for the UI currently in use. In this way, we may be confident that the solution will work for any past and future OS and theme. So, in order to update an application with the correct default font, we may use the SystemFonts class introduced in .NET 2.0. After some research, I discovered that...

SystemFonts.MessageBoxFont

...defaults to Segoe UI 9.25 on Windows Vista with Vista Theme and, for example, to Tahoma 8.25 on Windows XP with XP Theme. If we do not want to re-design our application, we could apply a post-initialization code that simply adjusts any control's font. We position it just below the Windows Forms initialization code:

InitializeComponent();

// Correct font
foreach (Control c in this.Controls)
{
    c.Font = new Font(SystemFonts.MessageBoxFont.FontFamily.Name, 8.25f);
}

The problem with this approach is that we lose any modification we made to our control font in the design view. So, for instance, if we set Label 1 to have font bold, we just lose this setting and get a normal style. A better approach is the following:

foreach (Control c in this.Controls)
{
    Font old = c.Font;
    c.Font =
        new Font(SystemFonts.MessageBoxFont.FontFamily.Name,
        8.25f, old.Style);
}

By doing this, we retain all information about the control font. We can just modify the font family and get the size and style we defined with, for instance, the Visual Studio form designer. This could be an optimal solution if it were not for the fact that Windows Vista now defaults to 9.25 point font size. We could just say that if the user is running Vista, then adjust to 9.25, else set 8.25 font size. The problem with this pseudo-algorithm is that we stick to a particular OS -- Vista, in this case -- and we just miss the fact that the user may have Windows Vista, but she may be using the classic theme. In this case, her default font is Tahoma 8.25. Again, we use SystemFonts to get a more universal solution:

foreach (Control c in this.Controls)
{
    Font old = c.Font;
    c.Font =
        new Font(SystemFonts.MessageBoxFont.FontFamily.Name,
        SystemFonts.MessageBoxFont.Size, old.Style);
}

Controls with custom size

We have now engineered a solution that, with a bunch of lines of code, adjusts our application so that it uses the correct default font for any combination of Windows OS and theme. A small problem arises when we use different or custom font sizes in the same form because we change the font and size of any control in the form. A suggestion may be to set the Tag property of the control to something -- i.e. "custom" -- so that the re-size of the control may be skipped:

foreach (Control c in this.Controls)
{
    Font old = c.Font;
    float size = c.Font.Size;

    if (c.Tag == null)
    {
        size = SystemFonts.MessageBoxFont.Size;
    }

    c.Font =
        new Font(SystemFonts.MessageBoxFont.FontFamily.Name,
        size, old.Style);
}

Even simpler

A problem with the above approach is that it assigns a new Font object to any control on the form. There may be an even simpler approach that consists of setting the default font for the form. Thanks go to Georgi Atanasov for pointing this out:

Font sysFont = SystemFonts.MessageBoxFont;
this.Font = new Font(sysFont.Name, sysFont.SizeInPoints, sysFont.Style);

In this case, any control of your form will get the correct font on any theme and will change accordingly. This approach works if you DO NOT modify the Font property of your controls, either directly in the code or in the Design View. In other words, the controls with a Font property set will retain their font. This can be just the expected behavior if we take care to modify the font property only for the controls that we want to have a different font than the default. Often, however -- especially if we work in a team where the interfaces come from designers rather than programmers -- this is not the case and we have to test on any theme to be sure of the results. Anyway, this latest solution is obviously more elegant.

Conclusions

The decision to dramatically change the look of the Windows Vista operating system heavily affects the existing application. The question is of sticking to the old style or designing a whole new user interface. My article just proposes a little escamotage to avoid redesign and to have a user interface that follows the user's operating system theme. Of course, this is not wholly satisfactory. For instance, labels should be adjusted in width and height while passing from 8.25 to 9.25 point size and a lot of other small fixings are to be made. However, I think this could be a good starting point.

History

  • 29 June, 2007 -- Original version posted
  • 19 July, 2007 -- Article updated

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Alessio Saltarin
Software Developer (Senior)
Italy Italy
Alessio Saltarin is Certified IT Architect and Senior Software Developer. He writes articles and book reviews for some italian magazines. He is the author of "Ruby e Rails" book.
Follow on   Twitter   Google+

Comments and Discussions

 
GeneralThe decision is not that simple PinmemberMihai Nita19-Jul-07 8:56 
GeneralInheritance PinmemberGeorgi Atanasov2-Jul-07 8:46 
GeneralRe: Inheritance PinmemberAlessio Saltarin4-Jul-07 3:33 
GeneralRe: Inheritance PinmemberGeorgi Atanasov4-Jul-07 9:39 
GeneralRe: Inheritance PinmemberNeal Andrews17-Jul-07 9:58 
GeneralGreat Article. PinmemberHumanBlade29-Jun-07 20:31 
GeneralRe: Great Article. PinmemberGeorgi Atanasov3-Jul-07 10:59 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140709.1 | Last Updated 19 Jul 2007
Article Copyright 2007 by Alessio Saltarin
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid