I need a quick way of forcing my C# Windows Forms application to not scale fonts when a user choose a larger or smaller percentage in the OS settings.
Is this even possible?
I need a quick way of forcing my C# Windows Forms application to not scale fonts when a user choose a larger or smaller percentage in the OS settings.
Is this even possible?
Here is what worked for me...
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.Font = new System.Drawing.Font("Arial", 14F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Pixel, ((byte)(0)));
The above two lines are copied from my BaseForm.Designer.cs file, but basically I found two easy steps to get "no font scaling":
Set AutoScaleMode to None.
Use "Pixel" as the Unit Type for all Fonts, instead of the default Point value.
As far as if you should let Windows scale your fonts or not, that's up to you. I for one don't like the design, so if I feel my application needs to be scaled, I'll do it myself, with my own options and design.
Over the years of speaking with actual end-users, I've also found that most of them have no idea about DPI settings, and if they have anything other than the default set, it wasn't because they wanted it that way... and they just never noticed because all they use is the web browser and maybe Excel and Microsoft Word (which use whatever font they set it to).
If my application had respected the system font settings, they wouldn't have liked it as much == less sales, because it would have had this huge ugly font like the system dialogs do (and they don't know how to change it, but they don't care about system dialogs they never use).
The problem is that the Font property of a Form or a control specifies the font size in Points. That's a measurement that affect the height of the letters when the DPI setting changes. One point is 1/72 inches. The default DPI, 96 dots per inch and a font size of 9 points yields a letter that is 9 / 72 x 96 = 12 pixels high.
When the user bumps up the DPI setting to, say, 120 DPI (125%) then the letter becomes 9 / 72 x 120 = 15 pixels high. If you don't let the control get larger then the text won't fit in the control anymore. Very ugly to look at.
The Form.AutoScaleMode property solves this problem. It checks at which size the form was designed and compares it against the DPI on the machine on which it runs. And resizes and relocates the controls to ensure this kind of clipping won't happen. Very useful, it is completely automatic without you having to do anything about it.
The typical problem is the "relocates" bit in the previous paragraph. If you give controls their own font size instead of inheriting the size of the form or if the automatic layout of the form isn't kosher then controls may end up in the wrong spot, destroying the organized look of the form.
You need to fix that, it isn't clear from your question what the source of the problem might be. Trying to prevent this auto-scaling from doing its job is not sustainable. You'll have to iterate all of the controls in the form and change their Font, picking a smaller font size. This is however going to get you into trouble a couple of years from now, if not already. Your user is going to complain about having to work with a postage stamp.
The easiest way to debug the layout problem, avoiding the pain of constantly changing the DPI size, is to temporarily paste this code into your form class:
protected override void OnLoad(EventArgs e) {
this.Font = new Font(this.Font.FontFamily, this.Font.SizeInPoints * 125 / 96);
base.OnLoad(e);
}
I found a pretty easy workaround.
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
This will make the text the same size regardless of the autoscale size.
Going against the user wishes like this is not something MS eagerly accommodates.
Rather than fixing the symptom (your app not scaling correctly), would it not be probably just as quick to fix the problem? When a user selects larger fonts, it's usually because they need the larger letters to be able to read them; so scaling correctly is more important than not scaling and remaining illegible to the user.
No. GDI and Windows Forms are resolution dependent. The best option is to design your layouts in a way that they scale appropriately when a window is resized. This tends to allow font size scaling to work correctly, as well, as the layouts will adjust as needed.
This, by the way, is one of the big improvements in WPF - it's designed to be resolution independent.
I suspect you already tried
yourform.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
in your forms, which prevents your forms from scaling, but not your fonts. So what you have to do (even if it is not recommended, see the other posts) is setting the font size for all controls in your form to a fixed size:
Here is a code snippet to grab all controls of a Form:
public List<Control> FindAllControls(Control container)
{
List<Control> controlList = new List<Control>();
FindAllControls(container, controlList);
return controlList;
}
private void FindAllControls(Control container, IList<Control> ctrlList)
{
foreach (Control ctrl in container.Controls)
{
if (ctrl.Controls.Count == 0)
ctrlList.Add(ctrl);
else
FindAllControls(ctrl, ctrlList);
}
}
Under http://www.csharp411.com/change-font-size/ you will find a link how to change the font size of a control, especially when you want to use fixed pixel sized. I think with these tools you can wire it together on your own.
EDIT: Don't forget to say: if you are finally going not to ignore the OS font size and to use AutoScaleMode as intended: this has some quirks, see my previous post here on SO.
So therefore, the only way to not to let your text auto scale on Windows 7 is to set the Font Unit as Pixel and the Window's AutoScaling property as None.
And in Windows 8.0, I guess you have no other choice but to set the dpi to the dpi of the developer machine and ask the user to never change it!