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

嵌入字体仅在Label生效,如何让DataGridView单元格应用自定义字体?

解决DataGridView嵌入自定义字体不生效的问题

问题根源

使用AddMemoryFont加载嵌入字体时,PrivateFontCollection中的字体并未被系统注册,而DataGridView的单元格渲染机制与Label不同——Label可以直接使用内存字体,但DataGridView更依赖系统已识别的字体,或需要确保字体对象与对应的PrivateFontCollection生命周期完全绑定。

解决方案

方案1:临时安装嵌入字体到系统(兼容性最优)

将嵌入字体写入临时文件并注册到系统,让DataGridView像使用系统字体一样加载它,应用退出时自动清理。

修改Program.cs代码:

internal static class Program
{
    [STAThread]
    static void Main()
    {
        ApplicationConfiguration.Initialize();
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(true);
        Application.Run(new Main());
    }

    static public Font InstallTempFont(byte[] fontData, float size, FontStyle style)
    {
        // 生成临时字体文件路径
        string tempFontPath = Path.Combine(Path.GetTempPath(), "Circulitos.ttf");
        File.WriteAllBytes(tempFontPath, fontData);

        // 注册字体到系统并通知系统更新
        AddFontResource(tempFontPath);
        SendMessage(HWND_BROADCAST, WM_FONTCHANGE, IntPtr.Zero, IntPtr.Zero);

        // 应用退出时清理临时文件与注册的字体
        Application.ApplicationExit += delegate {
            RemoveFontResource(tempFontPath);
            SendMessage(HWND_BROADCAST, WM_FONTCHANGE, IntPtr.Zero, IntPtr.Zero);
            if (File.Exists(tempFontPath)) File.Delete(tempFontPath);
        };

        return new Font("Circulitos", size, style);
    }

    // 导入Win32 API用于字体注册与通知
    [DllImport("gdi32.dll")]
    private static extern int AddFontResource(string lpFileName);
    [DllImport("gdi32.dll")]
    private static extern bool RemoveFontResource(string lpFileName);
    [DllImport("user32.dll")]
    private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

    private const int WM_FONTCHANGE = 0x001D;
    private static readonly IntPtr HWND_BROADCAST = new IntPtr(0xffff);
}

修改Main.cs调用逻辑:

public partial class Main : Form
{  
    private Font gf;

    public Main()
    {
        InitializeComponent();
        // 使用临时安装的字体
        gf = Program.InstallTempFont(Properties.Resources.Circulitos, 10, FontStyle.Regular);
        // 初始化DataGridView字体样式
        SetupDataGridViewFont();
    }

    private void SetupDataGridViewFont()
    {
        dataGridView1.EnableHeadersVisualStyles = false;
        // 设置所有单元格默认字体
        dataGridView1.DefaultCellStyle.Font = gf;
        // 设置表头字体
        dataGridView1.ColumnHeadersDefaultCellStyle.Font = gf;
        dataGridView1.RowHeadersDefaultCellStyle.Font = gf;
        // 手动刷新样式
        dataGridView1.Refresh();
    }
}

方案2:确保PrivateFontCollection生命周期与应用绑定

复用同一个PrivateFontCollection存储内存字体,避免因多个实例导致的字体对象失效,并通过CellFormatting事件强制设置单元格字体。

修改Program.cs代码:

internal static class Program
{
    static private PrivateFontCollection _fontCollection;

    [STAThread]
    static void Main()
    {
        ApplicationConfiguration.Initialize();
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(true);
        Application.ApplicationExit += delegate {
            _fontCollection?.Dispose();
        };
        Application.Run(new Main());
    }

    static public Font GetCustomFont(byte[] fontData, float size, FontStyle style)
    {
        if (_fontCollection == null)
        {
            _fontCollection = new PrivateFontCollection();
            IntPtr fontPtr = Marshal.AllocCoTaskMem(fontData.Length);
            Marshal.Copy(fontData, 0, fontPtr, fontData.Length);
            _fontCollection.AddMemoryFont(fontPtr, fontData.Length);
            Marshal.FreeCoTaskMem(fontPtr);
        }
        return new Font(_fontCollection.Families[0], size, style);
    }
}

修改Main.cs添加事件处理:

public partial class Main : Form
{  
    private Font gf;

    public Main()
    {
        InitializeComponent();
        gf = Program.GetCustomFont(Properties.Resources.Circulitos, 10, FontStyle.Regular);
        SetupDataGridViewFont();
        // 绑定CellFormatting事件确保字体生效
        dataGridView1.CellFormatting += DataGridView1_CellFormatting;
    }

    private void SetupDataGridViewFont()
    {
        dataGridView1.EnableHeadersVisualStyles = false;
        dataGridView1.DefaultCellStyle.Font = gf;
        dataGridView1.ColumnHeadersDefaultCellStyle.Font = gf;
        dataGridView1.RowHeadersDefaultCellStyle.Font = gf;
    }

    private void DataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
    {
        // 强制为每个单元格设置字体,避免样式被覆盖
        if (e.RowIndex >= 0 && e.ColumnIndex >= 0)
        {
            dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Style.Font = gf;
        }
    }
}

内容的提问来源于stack exchange,提问作者jhu unhn hefhd

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 12:34:58