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

.net Windows窗体应用程序的默认字体,.net,winforms,user-interface,fonts,appearance,.net,Winforms,User Interface,Fonts,Appearance,每次我在应用程序中创建新表单时,默认情况下它都使用“Microsoft Sans Serif,8.25pt”字体。我不会更改它,因为我知道在这种情况下,我的表单应该选择系统的默认字体。但是,当我运行应用程序时,使用的字体仍然不是Segoe UI(我的Windows Vista操作系统中的默认系统字体) 为什么会发生这种情况?如何确保我的应用程序看起来像一个普通的Windows应用程序?是的,它使用由GetStockObject返回的字体(默认的\u GUI\u字体)。这是无衬线女士。一种旧字体,

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


为什么会发生这种情况?如何确保我的应用程序看起来像一个普通的Windows应用程序?

是的,它使用由
GetStockObject返回的字体(默认的\u GUI\u字体)
。这是无衬线女士。一种旧字体,在大多数机器上早已过时。毫不奇怪,字体映射程序将其转换为Microsoft Sans Serif


据我所知,没有文档化的过程可以更改默认字体,SDK文档明确提到MS Sans Serif。如果你想要Segoe,你必须要它。这样做并不安全,仍然有很多XP机器没有Office2007。字体映射器将在没有Segoe的机器上进行翻译。不知道会弹出什么,我再也没有这样的机器了。

看看这篇关于表单中默认字体的讨论,它会导致您遇到的问题以及Microsoft的响应。简而言之,表单似乎没有获得(正确的)默认windows字体(您已更改)。

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


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

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

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

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

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

这种方法剩下的唯一问题是,如果要为特定控件(如粗体)设置字体样式。执行此操作的最佳位置仍然是表单的构造函数,从表单的字体作为基础开始,并从中修改样式:

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

组框内的控件实际上不受窗体字体属性的影响。原因是容器控件中的控件被视为容器控件(如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;
                }
            }        
        }

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

控件
的DefaultFont
是只读的;其中一个技巧是使用反射来覆盖它

Type settingsType = typeof(Control);
var defaultFontField = settingsType.GetField("defaultFont", BindingFlags.Static | BindingFlags.NonPublic);
defaultFontField.SetValue(null, new Font("Segoe UI", 8.25F));
请务必让UT密切关注这段代码,如果框架实现发生变化,没有API合同可以保护您


还要注意forms designer,它在大多数情况下都会在.designer类中逐字插入字体。

我已经尝试了针对
net472/net48
netcoreapp3.1
的示例应用程序。而.net应用程序
Control.DefaultFont
始终返回Microsoft无衬线且不缩放。但是.net core 3.1应用程序
Control.DefaultFont
返回的是win7/10上的系统字体,并且缩放良好。
所以,我想他们终于在core中解决了这个问题。

你注意到2008年有人问了一个问题吗?答案已经很晚了是的,我明白了,但在2015年我仍然需要这个问题的答案,我可以像我所说的那样意外地解决这个问题。所以,我想我应该告诉其他人这个解决方案,他们可能会有同样的问题,比如meThis,在某些情况下不能与远程桌面正常工作。如果服务器和客户端具有不同的默认字体(例如,英文窗口上的Microsoft Sans Serif为8.25磅,中文窗口上的SimSun为9磅),则启动或结束RDP会话将导致许多控件(包括Label)开始使用真实的默认字体进行渲染。当这种情况发生时,Font属性将继续返回您覆盖的值。这是一个非常老的问题,但我想知道答案今天是否仍然适用。假设一个应用程序在Windows 10;上运行WinForms应用程序;。默认字体问题是否已修复?“MS Sans Serif”与“Microsoft Sans Serif”不同。前者是一种旧的位图字体,后者在Win10中仍然广泛使用(控制面板、文件属性、基本上所有内置应用程序的对话框类型窗口,如regedit.exe或gpedit.msc中的[non-main window]对话框)。默认的图形用户界面字体为“MS S”
Type settingsType = typeof(Control);
var defaultFontField = settingsType.GetField("defaultFont", BindingFlags.Static | BindingFlags.NonPublic);
defaultFontField.SetValue(null, new Font("Segoe UI", 8.25F));