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

System.Drawing.Font使用PrivateFontCollection设置RichTextBox字体不生效

问题根因
  • 私有字体不生效:PrivateFontCollection如果声明为方法内局部变量,赋值完成后会被GC回收,非系统注册的私有字体对应的非托管资源被释放后,RichTextBox找不到有效字体资源会自动回退到默认Calibri字体。
  • 字体仅部分生效、末尾显示Calibri:SelectAll()方法不会选中RichTextBox内容末尾的隐式段落标记,未被选中的段落会沿用控件默认字体;如果是加载已有RTF文件的场景,RTF内嵌的字体表规则会覆盖控件属性设置的字体。
  • 生成的RTF文件仍显示Calibri:默认情况下RTF不会嵌入私有字体资源,未安装对应字体的设备打开文件时会自动替换为系统默认字体。
修复实现
  1. 将字体相关对象声明为类级别的全局变量,保持引用避免被GC回收:
// 放在窗体/自定义控件类的全局作用域,不要写在业务方法内部
private readonly System.Drawing.Text.PrivateFontCollection _privateFontCollection = new();
private Font _targetCustomFont;
  1. 初始化阶段加载私有字体,提前创建字体实例:
// 初始化逻辑(比如窗体构造函数、Load事件中执行)
_privateFontCollection.AddFontFile(@"C:\path\to\your\custom.ttf");
_targetCustomFont = new Font(_privateFontCollection.Families[0], 12f, FontStyle.Regular);
  1. 正确设置RichTextBox字体,覆盖全场景:
var RTB = new System.Windows.Forms.RichTextBox();
// 先设置控件全局默认字体,后续新输入内容会默认使用该字体
RTB.Font = _targetCustomFont;

// 针对已有内容/加载RTF后的场景,显式选中全部内容范围,不要用SelectAll()
RTB.Select(0, RTB.TextLength);
RTB.SelectionFont = _targetCustomFont;
// 取消全选,将光标定位到内容末尾
RTB.Select(RTB.TextLength, 0);

注意事项:只要RichTextBox还在使用该自定义字体,就不要主动释放_privateFontCollection和_targetCustomFont对象,否则资源回收后字体会再次失效。如果需要生成的RTF文件在未安装该字体的设备上正常显示,需要手动编写逻辑将字体数据嵌入RTF字体表。

内容的提问来源于stack exchange,提问作者Leonardo Ferrari

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 14:48:15