Is your feature request related to a problem? Please describe.
The default font has been updated in .NET Core 3.0 (#656) and documented. However for some users there is still an element of surprise when they migrate their apps to .NET Core.
We've received several questions regarding different sizes of forms (e.g. https://github.com/dotnet/winforms/issues/1122, https://github.com/dotnet/winforms/issues/1827, etc.).
Whilst the new default font is here to stay, some users may wish to retain the original font (e.g. due to a design of their app). However for an application with more than a handful of forms, setting the original font may be tedious and cumbersome exercise.
Describe the solution you'd like
Add the ability to set an application-wide font, similar to SetHighDpiMode() or SetCompatibleTextRenderingDefault() methods.
```C#
namespace System.Windows.Forms
{
public partial class Application
{
public void SetDefaultFont(Font font);
}
}
### API Usage
```C#
class Program
{
[STAThread]
static void Main()
{
Application.SetHighDpiMode(HighDpiMode.SystemAware);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.SetDefaultFont(new Font(new FontFamily("Microsoft Sans Serif"), 8f));
Application.Run(new Form1());
}
}
Will this feature affect UI controls?
No
We should totally do this for .NET 5, I think this is a great idea.
- This method must be "run only once" kind, i.e. a user may not be allowed to invoke it once an app has started.
Are you going to throw an exception when the SetDefaultFont is called after Run? If so, I'd throw InvalidOperationException.
- This method must be "run only once" kind, i.e. a user may not be allowed to invoke it once an app has started.
Are you going to throw an exception when the
SetDefaultFontis called afterRun? If so, I'd throwInvalidOperationException.
I propose we follow the same pattern set by SetCompatibleTextRenderingDefault() method and throw if SetDefaultFont() is called after the application has started:
https://github.com/dotnet/winforms/blob/18f1c8101085fd60a3eda7c95c796edc86c65820/src/System.Windows.Forms/src/System/Windows/Forms/Application.cs#L1208-L1215
The rationale behind it, if a form has been created, it may have been laid out and rendered using one font, the font may have been cached etc., and setting a new font could be detrimental from both performance and UX.
Is there already a way to get the default font? (Get/set symmetry)
probably Control.DefaultFont ?
Might be worthwhile to add a corresponding GetDefaultFont() to Application so that folks can just tweak parts, like:
```C#
[STAThread]
static void Main()
{
Application.SetHighDpiMode(HighDpiMode.SystemAware);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// Set default to 10pt
var font = Application.GetDefaultFont();
font = new Font(font.FontFamily, 10f);
Application.SetDefaultFont(font);
Application.Run(new Form1());
}
```
It would be odd if users had to call Control.DefaultFont to do this.
I don't think fonts are mutable, you have to construct a new one. (Not arguing against Application.GetDefaultFont for discoverability.)
I don't think fonts are mutable, you have to construct a new one. (Not arguing against Application.GetDefaultFont for discoverability.)
Fine, be like that ;-) Fixed sample.
The rationale behind this FR is to allow users to set the original font, that may have been used to design the app (i.e. _Font-scaling pixel-perfect_ design scenario), to help with a migration from .NET Framework to .NET Core/.NET.
To this end, users are expected to set both FontFamily and FontSize explicitly, and not leverage the current default font.
I don't feel that leveraging the default font to change its properties fits the above scenario. And, to be honest, I'm struggling to think of a use-case that would require this.
Do you have a use-case that would necessitate this?
Bump 馃槈
No objections, you're the domain expert. We just generally strive to avoid asymmetries like set-only APIs.
We just generally strive to avoid asymmetries like set-only APIs.
So do we, but in this case we want to have set-once kind of API, akin to SetHighDpiMode() or EnableVisualStyles().
Thank you
Reviewed and approved offline:
C#
namespace System.Windows.Forms
{
public partial class Application
{
public void SetDefaultFont(Font font);
}
}
Most helpful comment
I propose we follow the same pattern set by
SetCompatibleTextRenderingDefault()method and throw ifSetDefaultFont()is called after the application has started:https://github.com/dotnet/winforms/blob/18f1c8101085fd60a3eda7c95c796edc86c65820/src/System.Windows.Forms/src/System/Windows/Forms/Application.cs#L1208-L1215
The rationale behind it, if a form has been created, it may have been laid out and rendered using one font, the font may have been cached etc., and setting a new font could be detrimental from both performance and UX.