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

C# WinForm访问Chart后DataGridView DrawString绘制文字偏淡问题

问题描述

项目中多个DataGridView控件在CellPainting()事件处理方法中调用Graphics.DrawString()为指定列绘制自定义显示值,正常场景下文字渲染无异常。独立WinForm窗体中放置了DataVisualization.Charting.Chart控件用于展示简单折线图,存在如下异常现象:

  • 若先打开查看Chart图表,再查看自定义绘制的DataGridView单元格,DrawString()方法绘制出的文字会明显比正常效果更浅淡,即使手动将FontStyle从Regular修改为Bold,异常场景下绘制出的文字仍为Regular字重,无加粗效果
  • 若先查看任意一个自定义绘制的DataGridView,再打开查看Chart图表,所有自定义绘制的单元格文字会始终保持正常显示效果

已完成的排查操作:

  • 对比两种测试场景下的Graphics、Font对象,二者属性完全一致
  • 尝试创建静态Font对象供DrawString()调用,问题无任何改善

从现象判断,Chart控件似乎会以某种方式影响后续DrawString()调用时Font使用的FontWeight属性。因业务项目代码体量过大无法直接贴出,可编写简易双窗体应用复现问题,检索公开资料未找到同类问题反馈,现征集排查思路、解决方案或建议。


附:DataGridView CellPainting事件处理代码示例

private void GridView_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
    if (e.ColumnIndex == 3 && e.RowIndex >= 0)
    {
        Rectangle cellRect = new Rectangle(e.CellBounds.X + 1,
                                           e.CellBounds.Y + 1, 
                                           e.CellBounds.Width - 2,
                                           e.CellBounds.Height - 2);

        Color rowBackColor = dataGridView.Rows[e.RowIndex].DefaultCellStyle.BackColor;
        Color rowForeColor = SystemColors.WindowText;

        if (dataGridView.Rows[e.RowIndex].Selected)
        {
            rowBackColor = SystemColors.Highlight;
            rowForeColor = SystemColors.HighlightText;
        }

        using (Brush gridBrush = new SolidBrush(dataGridView.GridColor),
                foreColorBrush = new SolidBrush(rowForeColor),
                backColorBrush = new SolidBrush(rowBackColor))
        {
            using (Pen gridLinePen = new Pen(gridBrush))
            {
                // 擦除单元格原有内容
                e.Graphics.FillRectangle(backColorBrush, e.CellBounds);

                // 绘制网格线(仅绘制右侧、底部线条,其余线条由DataGridView自身处理)
                e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left, e.CellBounds.Bottom - 1, 
                                                                    e.CellBounds.Right  - 1,
                                                                    e.CellBounds.Bottom - 1);
                e.Graphics.DrawLine(gridLinePen, e.CellBounds.Right - 1,
                                                 e.CellBounds.Top, 
                                                 e.CellBounds.Right - 1,
                                                 e.CellBounds.Bottom);

                // 绘制单元格自定义文本内容
                if (e.Value != null)
                {
                    int    measureId    = Convert.ToInt32(e.Value.ToString());
                    string displayValue = ConvertToMeasure(measureId);

                    StringFormat stringFormat = new StringFormat(StringFormat.GenericDefault)
                    {
                        Alignment = StringAlignment.Near
                    };

                    e.Graphics.DrawString(displayValue, e.CellStyle.Font, foreColorBrush, cellRect, stringFormat);
                }

                e.Handled = true;
            }
        }
    }
}

问题根因与解决方案

该问题是老版本System.Windows.Forms.DataVisualization的已知状态泄漏Bug:Chart控件在GDI+渲染完成后,不会恢复修改过的进程全局GDI+文本渲染默认配置,会把全局默认文本渲染模式改为低质量、无加粗提示的模式;如果先加载渲染DataGridView,GDI+会提前完成字体缓存初始化,后续Chart修改的全局状态不会覆盖已生成的字体缓存,因此显示正常。

可通过以下任意一种方式修复:

  1. 每次绘制前显式指定Graphics文本渲染参数
    在CellPainting事件中调用DrawString前,手动给e.Graphics.TextRenderingHint赋值为高质量渲染模式,强制每次绘制使用指定参数,不受全局状态影响:
    // 放在DrawString调用之前即可
    e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
    
  2. 替换DrawString为TextRenderer.DrawText
    WinForm原生控件默认使用GDI实现的TextRenderer渲染文本,和GDI+的DrawString渲染栈完全独立,不会受Chart修改的GDI+全局状态影响,同时渲染效果和DataGridView原生单元格文字完全一致,不会出现字重不匹配、发虚、边距偏差的问题:
    // 替换原有DrawString调用即可
    TextRenderer.DrawText(e.Graphics, displayValue, e.CellStyle.Font, cellRect, rowForeColor, 
        TextFormatFlags.Left | TextFormatFlags.VerticalCenter | TextFormatFlags.NoPrefix);
    
  3. 升级Chart控件版本
    新版本的WinForm Chart控件已经修复了全局GDI+状态泄漏的问题,将项目引用的System.Windows.Forms.DataVisualization升级到最新稳定版即可直接解决。

优先推荐第二种方案,和DataGridView原生文字渲染效果一致性最高,无需额外调整渲染参数。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 23:00:17