views:

2084

answers:

3

So I was reading those Windows Vista UI guidelines someone linked to in another question, and they mentioned that you should be able to survive a switch to 120 DPI. Well, I fire up my handy VM with my app installed, and what do we get... AAAAGH!!! MASSIVE UI FAIL!

Everything's all jumbled: some containers aren't big enough for their text; some controls that were positioned "next to each other" are now all squished together/spread apart; some buttons aren't tall enough; my ListView columns aren't wide enough... eeek.

It sounds like a completely different approach is in order. My previous one was basically using the VS2008 Windows Forms designer to create, I guess, a pixel-based layout. I can see that if I were to stick with Windows Forms, FlowLayoutPanels would be helpful, although I've found them rather inflexible in the past. They also don't solve the problem where the containers (e.g. the form itself) aren't big enough; presumably there's a way to do that? Maybe that AutoSize property?

This might also be a sign that it's time to jump ship to WPF; I'm under the impression that it's specifically designed for this kind of thing.

The basic issue seems to come down to these:

  • If I were to stick with Windows Forms, what are all the tricks to achieving a font-size-independent layout that can survive the user setting his fonts large, or setting the display to 120 DPI?
  • Does WPF have significant advantages here, and if so, can you try to convince me that it's worth the switch?
  • Are there any general "best-practices" for font-size-independent layouts, either in the .NET stack or in general?
+2  A: 

If I were to stick with Windows Forms, what are all the tricks to achieving a font-size-independent layout that can survive the user setting his fonts large, or setting the display to 120 DPI?

For one, AutoScaleMode may be your friend.

Sören Kuklau
+3  A: 

In general, the problem is one of using two different "constants" for form layout, and then changing one of those constants without changing the other.

You are using pixels for your form entities, and points (basically inches) to specify font size. Pixels and points are related by DPI, so you change the DPI and suddenly your pixel fixed values don't line up with your point fixed values.

There are packages and classes for this, but at the end of the day you must choose one unit or the other, or scale one of the units according to the changing constant.

Personally, I'd change the entities on the form into inches. I'm not a C# person, so I don't know if this is supported natively, or if you have to perform some dynamic form sizing on application startup.

If you have to do this in your software, then go ahead and size everything normally (say, to your usual 96 DPI).

When your application starts, verify the system is at 96 DPI before you show your forms. If it is, great. If not, then set a variable with the correction factor, and scale and translate (modify both the location and size) of each entity before you show the form.

The ultimate, though, would be to specify everything in inches or points (a point is 1/72 of an inch) and let the OS deal with it. You might have to deal with corner cases (an outdoor screen with a correctly set DPI would show your application in a few pixels...)

Adam Davis
+8  A: 

Learn how the Anchor and Dock properties work on your controls, leave anything that can AutoSize itself alone, and use a TableLayoutPanel when you can.

If you do these three things, you'll get a lot of the WPF design experience in Windows Forms. A well-designed TableLayoutPanel will do its best to size the controls so that they fit the form properly. Combined with AutoSize controls, docking, and the AutoScaleMode mentioned by Soeren Kuklau you should be able to make something that scales well. If not, your form might just have too many controls on it; consider splitting it into tab pages, floating toolboxes, or some other space.

In WPF it's a lot easier because the concept of auto-sizing controls is built-in; in most cases if you are placing a WPF element by using a coordinate pair you are doing it wrong. Still, you can't change the fact that at lower resolutions it doesn't take much 120 dpi text to fill up the screen. Sometimes the problem is not your layout, but an attempt to put too much into a small space.

OwenP
I've always used Anchor, Dock, AutoSize and TableLayoutPanels to achieve UIs that are translatable and result in resizable forms. However, under high DPI settings with the "XP style DPI scaling" checkbox turned OFF I found every one of my apps has blurry fonts. Any tips on fixing that?
romkyns