Windows 窗体应用程序的默认字体

Posted

技术标签:

【中文标题】Windows 窗体应用程序的默认字体【英文标题】:Default font for Windows Forms application 【发布时间】:2010-09-22 19:11:23 【问题描述】:

每次我在我的应用程序中创建一个新表单时,它默认使用“Microsoft Sans Serif, 8.25pt”字体。我没有更改它,因为我知道在这种情况下,我的表单应该选择系统的默认字体。但是,当我运行我的应用程序时,使用的字体仍然是 Segoe UI(我在 Windows Vista 操作系统中的默认系统字体)。

为什么会这样?如何确保我的应用程序看起来像普通的 Windows 应用程序?

【问题讨论】:

这是一个非常古老的问题,但我想知道答案是否仍然适用于今天。假设一个人在 Windows 10 上的 WinForms 应用程序上工作;。默认字体问题是否已修复? 【参考方案1】:

接受的答案并没有真正回答问题;它只是解释了为什么会发生这种行为。

其他一些答案提出了可靠的解决方法,但我发现最好的解决方案确实是创建一个基本表单,您的应用程序中的所有表单都继承自该基本表单,并将该基本表单的 Font 属性设置为SystemFonts.MessageBoxFont in构造函数。这不仅可以确保您的应用程序在运行时根据用户的环境选择正确的字体(避免 Hans Passant 带来的潜在问题——没有 Office 2007 的 XP 将在没有 Segoe UI 的情况下求助于 Microsoft Sans Serif ),而且还为您提供了对当前 Windows 字体的设计时支持。在设计时使用正确的字体可以解决 Josuegomes 指出的问题,因为在表单上创建的任何容器控件都会在设计时获取表单使用的字体。

除了上述优点之外,这使您不必记住为您创建的每个表单修改构造函数,并确保应用程序中所有表单的一致性,并为您提供放置其他常用功能的位置。我以几种不同的方式使用它,例如 p/invoking 等,以修复 WinForms 实现中的错误。

这种方法剩下的唯一问题是,如果您想为特定控件设置字体样式,例如粗体。这样做的最佳位置仍然是在该表单的构造函数中,从表单的字体作为基础开始并从中修改样式:

myControl.Font = New Font(Me.Font, FontStyle.Bold)

【讨论】:

【参考方案2】:

您可以在表单构造函数中的 InitializeComponent() 之前添加:

this.Font = SystemFonts.MessageBoxFont;

这似乎适用于 Windows XP 和 Windows Vista。

【讨论】:

【参考方案3】:

查看此 blog entry 谈论表单中的默认字体,这会导致您遇到问题,以及此 Connect Bug 与 Microsoft 的响应。简而言之,Forms 似乎没有获得(正确的)默认 windows 字体(您已更改)。

【讨论】:

【参考方案4】:

是的,它使用GetStockObject(DEFAULT_GUI_FONT) 返回的字体。这是 MS 无衬线字体。一种旧字体,大多数机器早已不复存在。毫不奇怪,字体映射器将其翻译为 Microsoft Sans Serif。

据我所知,没有记录的程序可以更改该默认字体,SDK 文档明确提到了 MS Sans Serif。如果您想要 Segoe,则必须提出要求。这样做并不安全,仍然有很多没有 Office 2007 的 XP 机器。字体映射器将在没有 Segoe 可用的机器上翻译它。不知道弹出什么,我已经没有这样的机器了。

【讨论】:

“MS Sans Serif”与“Microsoft Sans Serif”不同。前者是旧的位图字体,后者在 Win10 中仍然广泛使用(控制面板、文件属性、基本上所有内置应用程序的对话框类型窗口,如 regedit.exe 或 gpedit 中的 [非主窗口] 对话框) .MSC)。 DEFAULT_GUI_FONT 是 8pt 的“MS Shell Dlg”。并且“MS Shell Dlg”是WinXP到Win10上的“Microsoft Sans Serif”,但不是通用的。例如,它在中文或日文系统上是不同的字体。而且它很普遍,因为原生对话框资源默认使用它,包括在 Windows 自己的程序中。【参考方案5】:

组框内的控件确实不受窗体的 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;
                
                    
        

【讨论】:

【参考方案6】:

如果您有带有关联控件的组框,则将窗体的 Font 属性设置为 SystemFonts.DialogFont 不起作用。组框内的控件不受窗体的 Font 属性的影响。我通过将每个组框的 Font 属性设置为 SystemFonts.DialogFont 来“解决”这个问题。

【讨论】:

【参考方案7】:

试试这个,单击一个表单并更改字体大小,例如,我将表单的字体大小更改为 12pt,然后通过将文本框拖到表单进行测试。您会看到,文本框大小也更改为 12pt。我只是偶然得到了这个解决方案。

【讨论】:

您注意到 2008 年有人问过一个问题吗?这是很晚的答案 是的,我明白了,但是在 2015 年我仍然需要这个问题的答案,我可以按照我所说的偶然解决这个问题。所以,我想我应该把这个解决方案告诉其他可能会遇到和我一样问题的人【参考方案8】:

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 类中逐字插入字体。

【讨论】:

这在某些情况下无法与远程桌面一起正常工作。如果服务器和客户端具有不同的默认字体(例如,英文 Windows 上的 8.25 pt Microsoft Sans Serif 与中文 Windows 上的 9 pt SimSun),那么启动或结束 RDP 会话将导致包括标签在内的许多控件开始渲染真正的默认字体。发生这种情况时,Font 属性将继续返回您覆盖的值。【参考方案9】:

在 .NET Core 中,我们(.NET 团队)将默认字体更新为 Segoe UI,在 .NET 6 中,我们添加了一个 API 来更改整个应用程序的默认字体。

<PropertyGroup>里面的项目文件中添加:

<ApplicationDefaultFont>Curlz MT, 18pt</ApplicationDefaultFont>

这将更新设计器和正在运行的应用程序中使用默认字体的每个控件(您未明确覆盖的所有内容)。

您也可以直接在您的Main() 中调用Application.SetDefaultFont(),如下例所示:

static void Main()

    ApplicationConfiguration.Initialize();

    Application.SetDefaultFont(new Font(new FontFamily("Curlz MT"), 18f));

    Application.Run(new AirQualityForm());

这将更新您正在运行的应用程序中的字体,但不会更新设计器中的字体。

【讨论】:

【参考方案10】:

我已经尝试了针对net472/net48netcoreapp3.1 的示例应用程序。而 .net app Control.DefaultFont 总是返回 Microsoft Sans Serif 而不是缩放。但是 .net core 3.1 应用程序Control.DefaultFont 在 win7/10 上准确返回系统字体并且可以很好地缩放。 所以,我认为他们最终在核心中解决了这个问题。

【讨论】:

【参考方案11】:

我对此有一个非常简单的建议。只需选择表格并从属性面板中选择所需的字体。而且 viola,您所做的每个控件都会将您选择的字体作为默认字体。

【讨论】:

希望对您有所帮助:)

以上是关于Windows 窗体应用程序的默认字体的主要内容,如果未能解决你的问题,请参考以下文章

winform 默认的窗体边框颜色是黄色的? 而且为啥程序运行了后 窗体大小 控件间距 还有字体 感觉不一样?

Windows 窗体文本框字体颜色限时更改

Delphi默认窗体随想

如何使用 c# 从 Windows 窗体向用户显示默认的 Windows 身份验证提示?

初识Windows程序

.NET 如何更改 windows 默认字体?