.NET Framework 4.8 WinForms如何不安装直接加载TTF字体?
解决方案:无需安装直接加载本地字体
可以不安装字体直接从文件加载,你的问题出在创建Font对象的方式——通过字体名称字符串创建时,系统会优先查找已安装的字体,而非PrivateFontCollection中加载的私有字体。以下是修复步骤和修改后的代码:
问题根源
你当前通过new Font(familyName, ...)创建字体,系统会尝试匹配系统已安装的字体名称,找不到则使用回退字体。正确的做法是直接使用PrivateFontCollection中返回的FontFamily实例来创建Font。
修改后的代码
public partial class Form1 : Form { private PrivateFontCollection _privateFontCollection; // 保留引用,避免提前释放 private FontFamily[] _fontFamilies; public Form1() { InitializeComponent(); _privateFontCollection = new PrivateFontCollection(); string[] ttfFiles = Directory.GetFiles(@"path to the fonts", "*.ttf"); foreach (string ttfFile in ttfFiles) { _privateFontCollection.AddFontFile(ttfFile); } _fontFamilies = _privateFontCollection.Families; Disposed += (_, _) => { Console.WriteLine("Disposing"); _privateFontCollection.Dispose(); }; } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); PointF pointF = new PointF(10, 0); using (SolidBrush solidBrush = new SolidBrush(Color.Black)) // 使用using释放资源 { foreach (var fontFamily in _fontFamilies) { string familyName = fontFamily.Name; if (fontFamily.IsStyleAvailable(FontStyle.Regular)) { // 直接用FontFamily实例创建Font,而非名称字符串 using (Font regFont = new Font(fontFamily, 16, FontStyle.Regular, GraphicsUnit.Pixel)) { e.Graphics.DrawString( $"{familyName} {FontStyle.Regular}", regFont, solidBrush, pointF); pointF.Y += regFont.Height; } } // 其他样式同理,比如Bold、Italic等 if (fontFamily.IsStyleAvailable(FontStyle.Bold)) { using (Font boldFont = new Font(fontFamily, 16, FontStyle.Bold, GraphicsUnit.Pixel)) { e.Graphics.DrawString( $"{familyName} {FontStyle.Bold}", boldFont, solidBrush, pointF); pointF.Y += boldFont.Height; } } pointF.Y += 10; } } } }
额外注意事项
- 保留PrivateFontCollection引用:不要在构造函数中直接释放或让其超出作用域,Font对象依赖该集合,必须在所有使用该字体的控件/绘图操作完成后再释放(如Form的Disposed事件)。
- 加载所有字体文件:B612字体通常包含多个文件(对应不同样式),确保所有相关.ttf/.otf文件都被加载到PrivateFontCollection中,否则某些样式可能无法正常显示。
- 资源释放:使用
using语句包裹Font和Brush,确保GDI+资源及时释放,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Stelios Adamantidis
相关产品推荐
相关产品推荐

