You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 06:05:06