Resolution Independent WPF Apps

Working with aging hardware is tough.

For the last couple of years I’ve been working for a manufacturing company, creating a new application that would instruct the operators on the manufacturing line on how to assemble the hardware.

It needs to be really clear, and due to the amount of information they need, the UI is pretty full, with every square inch used up with “high-priority” information. The old version of this app was written in VB6, and the new in WPF.

Luckily, my managers have been on board with me buying new hardware for the manufacturing lines, so I’ve been able to use shiny new PCs with nice 1080p monitors for the operators on the line. Perhaps I’ve been spoiled by my years in software development, because I’d kind of forgotten that people have monitors that are not 1920×1080. I’m used to reading about specs for brand new laptops that are now pushing 4k.

Unfortunately, these brand new computers are not the only place I have to deploy my app. It turns out people want this to run on their desk PCs, which brings me back around to this; working with aging hardware is tough.

More recently I’ve started deploying my app in person to these plants around the country, and I’ve found I’m much more likely to find one of these

crap pc

Than one of these

nice pc

Now, you may be asking, what kind of resolution does one of these lovely PCs provide? Well, it turns out, it can range, quite significantly. It’s almost definitely not 1080p, but I’m fairly sure I’ve stumbled across an 800 x 600 monitor buried underneath an inch of dust. You can see my dilemma here.

Now, this shouldn’t be a problem, Microsoft claims WPF is resolution independent. In theory, I guess it is, but I’ll let StackOverflow explain my problem.

resolution independent

So it will adapt your screen to the resolution. The problem comes when you’re using a large size 20 font for a title. In 1080p it all looks totally reasonable, but down in 800 x 600, it takes up 1/4 of the screen. It still shows everything, but not in any kind of human-usable way.

Obviously this won’t work.

To fix this problem, I created a panel called ResolutionIndependentPanel. It’s pretty simple, I basically take a ScaleTransform and scale the entire contents of the panel based on the resolution of the screen it’s being displayed on. You supply it with the resolution you designed it on, in this case it’s 1920×1080, but it could be anything, and it figures out if it needs to up or downscale to make it look pretty similar in any resolution.

The goal is to end up with the same usable space. If your textbox took up 10% of the screen on the “designed” resolution, then it should take up that same 10% on an 800×600 monitor. Here’s a screenshot to give you an idea of what I’ve done here

panel comparison

As you can see, they have the same proportional layout and if you were to look at this on an 800×600 monitor, everything would look pretty normal.

OK, that’s basically all it does, I’m a big fan of simple fixes, and I’m going to be rolling out this one in my app this week, so I thought I’d share. It’s available in NuGet for .NET 4+, just search for ResolutionIndependentPanel.

To use it, just set up the namespace in the declarations of your UserControl or Window and wrap all your content inside of the ResolutionIndependentPanel. DesignHeight and DesignWidth have to be set to your design resolution. Piece of cake, right?


<rip:ResolutionIndependentPanel DesignHeight="1080"
    <Grid>{ Your Content }</Grid>


Be careful with the scaling though. There are some known pitfalls. If you are a big fan of modern design, you might be using the built-in drop shadow effects. Well, unfortunately, these do something weird to the scale transforms. I think what’s happening is that WPF is taking a bitmap of the control and scaling that, instead of scaling it as a vector. Something like that, but you end up with blurry text and controls. In this case, maybe try and create your own drop shadows (I made mine out of Rectangles) to workaround it.


P.S. If you think this is helpful, check out my other simple WPF panel fix, AirspaceFixer, it’s also available in Nuget and is based on a GitHub project.