Windows 窗体应用程序的默认字体
每次我在应用程序中创建新表单时,它都会默认使用“Microsoft Sans Serif,8.25pt”字体。 我不会更改它,因为我知道在这种情况下,我的表单应该选择系统的默认字体。 然而,当我运行我的应用程序时,使用的字体仍然不是 Segoe UI(我的 Windows Vista 操作系统中的默认系统字体)。
为什么会出现这种情况? 如何确保我的应用程序看起来像普通的 Windows 应用程序?
Every time that I create a new form in my application, it uses the "Microsoft Sans Serif, 8.25pt" font by default. I'm not changing it because I know that in this case my form should pick up whatever the default font is for the system. However, when I run my application, the font that is used is still anything but Segoe UI (my default system font in my Windows Vista OS).
Why does this happen? How do I make sure that my application looks like a normal Windows application?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
接受的答案并没有真正回答问题; 它只是解释了为什么会发生这种行为。
其他一些答案提出了可靠的解决方法,但我发现最好的解决方案实际上是创建一个基本表单,应用程序中的所有表单都继承自该基本表单,并将此基本表单的 Font 属性设置为 SystemFonts.MessageBoxFont< /code> 在构造函数中。 这不仅可以确保您的应用程序在运行时根据用户环境选择正确的字体(避免 Hans Passant 带来的潜在问题 — 没有 Office 2007 的 XP 在没有 Segoe UI 的情况下将诉诸 Microsoft Sans Serif ),同时还为您提供对当前 Windows 字体的设计时支持。 在设计时使用正确的字体可以解决 Josuegomes 指出的问题,因为在窗体上创建的任何容器控件都将采用窗体在设计时使用的字体。
除了上述优点之外,这还使您不必记住修改您创建的每个表单的构造函数,并确保应用程序中所有表单的一致性,并为您提供放置其他常用功能的位置。 我以几种不同的方式使用它,例如 p/invoking 等来修复 WinForms 实现中的错误。
这种方法剩下的唯一问题是,如果您想为特定控件设置字体样式,例如粗体。 执行此操作的最佳位置仍然是在该表单的构造函数中,从表单的字体作为基础开始并从中修改样式:
The accepted answer doesn't really answer the question; it just explains why this behavior is occurring.
Some of the other answers propose solid workarounds, but I've found that the best solution really is to create a base form that all of the forms in your application inherit from and set this base form's Font property to
SystemFonts.MessageBoxFont
in the constructor. This not only ensures that your application picks up the correct font at run-time, based on the user's environment (heading off the potential problem posed by Hans Passant—an XP without Office 2007 will resort to Microsoft Sans Serif in the absence of Segoe UI), but also gives you design-time support for your current Windows font. Using the correct font at design time solves the problem Josuegomes points out, because any container control that is created on the form will pick up the font used by the form at design-time.Besides the above advantages, this frees you from having to remember to modify the constructor for each form that you create and ensures consistency across all of the forms in your application, as well as giving you a place to put other common functionality. I use this in a couple of different ways such as p/invoking, etc. to fix bugs in the WinForms implementation.
The only problem that remains with this approach is if you want to set a font style for a particular control, such as bold. The best place to do this is still in that form's constructor, starting with the form's font as a base and modifying the style from it:
您可以在 Form 构造函数中的 InitializeComponent() 之前添加:
这似乎适用于 Windows XP 和 Windows Vista。
You can add before InitializeComponent() in the Form constructor(s):
This appear to work with Windows XP and Windows Vista.
查看此博客文章,讨论默认字体导致您遇到问题的表单以及此 Connect Bug以及微软的回应。 简而言之,Forms 似乎没有获得(正确的)默认 Windows 字体(您已更改)。
Check out this blog entry talking about the default font in Forms which leads to the problem you are experiencing and this Connect Bug with Microsoft's response. In short it just seems that Forms does not get the (correct) default windows font (which you have changed).
是的,它使用
GetStockObject(DEFAULT_GUI_FONT)
返回的字体。 这是 MS Sans Serif。 一种旧字体,在大多数机器上早已消失。 毫不奇怪,字体映射器将其转换为 Microsoft Sans Serif。据我所知,没有记录的程序可以更改默认字体,SDK 文档明确提到了 MS Sans Serif。 如果你想要 Segoe,你就必须提出要求。 这样做不太安全,仍然有很多 XP 计算机没有安装 Office 2007。字体映射器将在没有 Segoe 可用的计算机上对其进行翻译。 不知道会弹出什么,我已经没有这样的机器了。
Yes, it uses the font returned by
GetStockObject(DEFAULT_GUI_FONT)
. Which is MS Sans Serif. An old font, long gone from most machines. The font mapper translate it to, no surprise, Microsoft Sans Serif.There is no documented procedure I know of to change that default font, the SDK docs mention MS Sans Serif explicitly. If you want Segoe, you'll have to ask for it. Which isn't that safe to do, there are still a lot of XP machines out there without Office 2007. The font mapper will translate it on a machine that doesn't have Segoe available. Not sure what pops out, I don't have such a machine left anymore.
在 .NET Core 中,我们(.NET 团队)将默认字体更新为 Segoe UI,在 .NET 6 中,我们添加了一个 API 来更改整个应用程序的默认字体。
在
内的项目文件中添加:这将更新设计器和正在运行的应用程序中使用默认字体的每个控件(您未显式覆盖的所有内容)。
您还可以直接在
Main()
中调用Application.SetDefaultFont()
,如下例所示:这将更新正在运行的应用程序中的字体,但不会更新设计器中的字体。
In .NET Core we (.NET team) updated the default font to Segoe UI and in .NET 6 we have added an API to change your default font all over your application.
In project file inside
<PropertyGroup>
add:This will update every control that is using the default font (everything that was not explicitly overwritten by you) in the designer and your running application.
You can also call
Application.SetDefaultFont()
directly in youMain()
like in the example below:this will update the font in your running application but not in the designer.
组框内的控件确实不受窗体的 Font 属性的影响。 原因是容器控件中的控件被视为容器控件(如 groupbox)的子控件,而不是主窗体的子控件。 为了使所有控件(包括组框中的控件)正确缩放,您可以使用类似于以下的代码:
The controls inside the group box are indeed not affected by the form's Font property. The reason is that controls in container controls are treated as children of the container controls like groupbox, but not children of the main form. In order for all controls including those in groupboxes to scale properly, you can use code similar to below:
如果您有带有关联控件的组框,则将窗体的 Font 属性设置为 SystemFonts.DialogFont 不起作用。 组框内的控件不受窗体的 Font 属性影响。 我通过将每个组框的 Font 属性设置为 SystemFonts.DialogFont 来“解决”这个问题。
Setting the form's Font property to SystemFonts.DialogFont doesn't work if you have group boxes with associated controls. The controls inside the group box are not affected by the form's Font property. I "solved" this by setting the Font property to SystemFonts.DialogFont for each and every group box.
试试这个,单击表单并更改字体大小,例如我将表单的字体大小更改为 12pt,然后通过将文本框拖动到表单进行测试。 您会看到,文本框大小也更改为 12pt。 我只是偶然得到了这个解决方案。
Try this, Click a Form and change font size for example I changed a font size of Form to 12pt and then test by drag text box to the Form. You'll see, The textbox size is changed to 12pt as well. I've just got this solution by accident.
Control.DefaultFont
是只读的; 重写它的一个技巧是使用反射。请务必让 UT 密切关注此代码,如果框架实现发生变化,没有 API 合同可以保护您。
还要注意表单设计器,大多数时候会在 .designer 类中逐字插入字体。
The
Control.DefaultFont
is ReadOnly; one hacky was to overwrite it is to use reflection.Be sure to have a UT keeping an eye on this code, there is no API contract to protect you if the Framework implementation changes.
Also be aware of forms designer which most of the time will insert the font verbatim in .designer classes.
我尝试过同时针对
net472/net48
和netcoreapp3.1
的示例应用程序。 而.net应用程序Control.DefaultFont
始终返回Microsoft Sans Serif并且不缩放。 但是.net core 3.1应用Control.DefaultFont
返回的正是win7/10上的系统字体,并且缩放得很好。所以,我认为他们最终在核心解决了这个问题。
I've tried sample app that targets both
net472/net48
andnetcoreapp3.1
. While .net appControl.DefaultFont
always returns Microsoft Sans Serif and not scaled. But .net core 3.1 appControl.DefaultFont
returns exactly the system font on win7/10 and scaled well.So, I think they fixed this in core at last.
我对此有一个非常简单的建议。 只需选择表单并从属性面板中选择所需的字体即可。 和中提琴一样,您制作的每个控件都会将您选择的字体作为默认字体。
I have a very easy suggestion for this one. Just select the form and choose your required font from the properties panel. And viola, every control you make will have your selected font as the default font.