每次我在我的应用程序中创建一个新表单时,它默认使用“Microsoft Sans Serif,8.25pt”字体。我没有更改它,因为我知道在这种情况下,我的表单应该选择系统的默认字体。但是,当我运行我的应用程序时,使用的字体仍然是 Segoe UI(我在 Windows Vista 操作系统中的默认系统字体)。
为什么会这样?如何确保我的应用程序看起来像普通的 Windows 应用程序?
每次我在我的应用程序中创建一个新表单时,它默认使用“Microsoft Sans Serif,8.25pt”字体。我没有更改它,因为我知道在这种情况下,我的表单应该选择系统的默认字体。但是,当我运行我的应用程序时,使用的字体仍然是 Segoe UI(我在 Windows Vista 操作系统中的默认系统字体)。
为什么会这样?如何确保我的应用程序看起来像普通的 Windows 应用程序?
接受的答案并没有真正回答问题。它只是解释了为什么会发生这种行为。
其他一些答案提出了可靠的解决方法,但我发现最好的解决方案确实是创建一个基本表单,应用程序中的所有表单都继承自该基本表单,SystemFonts.MessageBoxFont
并在构造函数中将此基本表单的 Font 属性设置为。这不仅可以确保您的应用程序在运行时根据用户的环境选择正确的字体(避免 Hans Passant 带来的潜在问题——没有 Office 2007 的 XP 将在没有 Segoe UI 的情况下求助于 Microsoft Sans Serif ),而且还为您提供了对当前 Windows 字体的设计时支持。在设计时使用正确的字体可以解决 Josuegomes 指出的问题,因为在表单上创建的任何容器控件都会在设计时获取表单使用的字体。
除了上述优点之外,这使您不必记住为您创建的每个表单修改构造函数,并确保应用程序中所有表单的一致性,并为您提供放置其他常用功能的位置。我以几种不同的方式使用它,例如 p/invoking 等,以修复 WinForms 实现中的错误。
这种方法剩下的唯一问题是,如果您想为特定控件设置字体样式,例如粗体。执行此操作的最佳位置仍然是在该表单的构造函数中,从表单的字体作为基础开始并从中修改样式:
myControl.Font = New Font(Me.Font, FontStyle.Bold)
您可以在 Form 构造函数中的 InitializeComponent() 之前添加:
this.Font = SystemFonts.MessageBoxFont;
这似乎适用于 Windows XP 和 Windows Vista。
查看此博客条目,讨论 Forms 中的默认字体,这会导致您遇到的问题以及Microsoft 的响应中的此Connect Bug 。简而言之,Forms 似乎没有获得(正确的)默认 windows 字体(您已更改)。
是的,它使用返回的字体GetStockObject(DEFAULT_GUI_FONT)
。这是 MS 无衬线字体。一种旧字体,大多数机器早已不复存在。毫不奇怪,字体映射器将其转换为 Microsoft Sans Serif。
我知道没有记录的程序可以更改该默认字体,SDK 文档明确提到了 MS Sans Serif。如果您想要 Segoe,则必须提出要求。这样做并不安全,仍然有很多没有 Office 2007 的 XP 机器。字体映射器将在没有 Segoe 可用的机器上翻译它。不知道会弹出什么,我已经没有这样的机器了。
组框内的控件确实不受窗体的 Font 属性的影响。原因是容器控件中的控件被视为容器控件(如 groupbox)的子控件,而不是主窗体的子控件。为了使所有控件(包括 groupbox 中的控件)正确缩放,您可以使用类似于以下的代码:
foreach (Control ctr in this.Controls)
{
ctr.Font = SystemFonts.IconTitleFont;
// controls in groupboxes are not child of main form
if (ctr.HasChildren)
{
foreach (Control childControl in ctr.Controls)
{
childControl.Font = SystemFonts.IconTitleFont;
}
}
}
如果您有带有关联控件的组框,则将窗体的 Font 属性设置为 SystemFonts.DialogFont 不起作用。组框内的控件不受窗体的 Font 属性的影响。我通过将每个组框的 Font 属性设置为 SystemFonts.DialogFont 来“解决”这个问题。
试试这个,单击一个表单并更改字体大小,例如我将表单的字体大小更改为 12pt,然后通过将文本框拖动到表单进行测试。您会看到,文本框大小也更改为 12pt。我只是偶然得到了这个解决方案。
Control.DefaultFont
是只读的;一个hacky是覆盖它是使用反射。
Type settingsType = typeof(Control);
var defaultFontField = settingsType.GetField("defaultFont", BindingFlags.Static | BindingFlags.NonPublic);
defaultFontField.SetValue(null, new Font("Segoe UI", 8.25F));
确保让 UT 密切关注此代码,如果框架实现发生更改,没有 API 合约可以保护您。
还要注意表单设计器,它大多数时候会在 .designer 类中逐字插入字体。
在 .NET Core 中,我们(.NET 团队)将默认字体更新为 Segoe UI,在 .NET 6 中,我们添加了一个 API 来更改整个应用程序的默认字体。
在项目文件里面<PropertyGroup>
添加:
<ApplicationDefaultFont>Curlz MT, 18pt</ApplicationDefaultFont>
这将更新设计器和正在运行的应用程序中使用默认字体的每个控件(您未明确覆盖的所有内容)。
您也可以像下面的示例一样Application.SetDefaultFont()
直接调用您Main()
:
static void Main()
{
ApplicationConfiguration.Initialize();
Application.SetDefaultFont(new Font(new FontFamily("Curlz MT"), 18f));
Application.Run(new AirQualityForm());
}
这将更新您正在运行的应用程序中的字体,但不会更新设计器中的字体。
我已经尝试过同时针对net472/net48
和的示例应用程序netcoreapp3.1
。虽然 .net 应用程序Control.DefaultFont
始终返回 Microsoft Sans Serif 并且未缩放。但是 .net core 3.1 应用程序Control.DefaultFont
在 win7/10 上完全返回系统字体并且缩放良好。所以,我认为他们最终在核心中解决了这个问题。
我对此有一个非常简单的建议。只需选择表单并从属性面板中选择所需的字体。中提琴,您所做的每个控件都会将您选择的字体作为默认字体。