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

WinForms DataGridView列宽不足时如何隐藏文本左侧内容?

在.NET 6 WinForms DataGridView实现左侧截断文本(...DEFG)

默认情况下,DataGridView的文本截断逻辑是从右侧截断,仅设置MiddleRight对齐只会调整文本在单元格内的位置,不会改变截断方向。要实现左侧截断(开头隐藏、末尾保留加省略号),常用两种方案:

方法一:通过CellPainting事件自定义绘制

这是无需额外控件的快速实现方式,直接在已有DataGridView上绑定事件处理:

  1. 给DataGridView绑定CellPainting事件
  2. 在事件逻辑中跳过标题行/空单元格,计算文本宽度,判断是否需要截断
  3. 手动绘制单元格背景、边框,再绘制左侧截断后的文本

示例代码:

private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
    // 跳过标题行和空值单元格
    if (e.RowIndex < 0 || e.Value == null) return;

    string cellText = e.Value.ToString();
    // 计算单元格内可用于显示文本的区域(扣除内边距)
    var textArea = new Rectangle(
        e.CellBounds.X + e.CellStyle.Padding.Left,
        e.CellBounds.Y + e.CellStyle.Padding.Top,
        e.CellBounds.Width - e.CellStyle.Padding.Left - e.CellStyle.Padding.Right,
        e.CellBounds.Height - e.CellStyle.Padding.Top - e.CellStyle.Padding.Bottom
    );

    int textWidth = TextRenderer.MeasureText(cellText, e.CellStyle.Font).Width;
    if (textWidth > textArea.Width)
    {
        // 取消默认绘制,避免重叠
        e.Handled = true;
        // 绘制单元格背景和边框
        e.PaintBackground(e.CellBounds, true);
        e.PaintBorder(e.CellBounds, e.CellStyle, DataGridViewAdvancedBorderStyle.All);
        // 生成左侧截断的文本
        string truncatedText = GetLeftTruncatedText(cellText, e.CellStyle.Font, textArea.Width);
        // 右对齐垂直居中绘制文本
        TextRenderer.DrawText(e.Graphics, truncatedText, e.CellStyle.Font, textArea, 
            e.CellStyle.ForeColor, TextFormatFlags.Right | TextFormatFlags.VerticalCenter);
    }
}

// 辅助方法:根据可用宽度生成左侧截断的文本
private string GetLeftTruncatedText(string text, Font font, int maxWidth)
{
    int ellipsisWidth = TextRenderer.MeasureText("...", font).Width;
    int availableWidth = maxWidth - ellipsisWidth;
    if (availableWidth <= 0) return "...";

    // 从文本末尾向前截取,直到内容宽度不超过可用空间
    for (int i = text.Length - 1; i >= 0; i--)
    {
        string subText = text.Substring(i);
        if (TextRenderer.MeasureText(subText, font).Width <= availableWidth)
        {
            return "..." + subText;
        }
    }
    return "...";
}

方法二:自定义DataGridView单元格类型

如果需要在多个DataGridView中复用该功能,建议封装自定义单元格:

  1. 继承DataGridViewTextBoxCell并重写Paint方法,内置左侧截断逻辑
  2. (可选)创建对应列类,方便在设计器中直接使用

示例代码:

public class DataGridViewLeftTruncatedTextBoxCell : DataGridViewTextBoxCell
{
    protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
    {
        if (formattedValue == null)
        {
            base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
            return;
        }

        string cellText = formattedValue.ToString();
        var textArea = new Rectangle(
            cellBounds.X + cellStyle.Padding.Left,
            cellBounds.Y + cellStyle.Padding.Top,
            cellBounds.Width - cellStyle.Padding.Left - cellStyle.Padding.Right,
            cellBounds.Height - cellStyle.Padding.Top - cellStyle.Padding.Bottom
        );

        int textWidth = TextRenderer.MeasureText(cellText, cellStyle.Font).Width;
        if (textWidth > textArea.Width)
        {
            // 只绘制背景、边框,跳过默认文本绘制
            var modifiedPaintParts = paintParts & ~DataGridViewPaintParts.ContentForeground;
            base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, modifiedPaintParts);
            // 绘制左侧截断后的文本
            string truncatedText = GetLeftTruncatedText(cellText, cellStyle.Font, textArea.Width);
            TextRenderer.DrawText(graphics, truncatedText, cellStyle.Font, textArea, cellStyle.ForeColor, TextFormatFlags.Right | TextFormatFlags.VerticalCenter);
        }
        else
        {
            base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
        }
    }

    private string GetLeftTruncatedText(string text, Font font, int maxWidth)
    {
        int ellipsisWidth = TextRenderer.MeasureText("...", font).Width;
        int availableWidth = maxWidth - ellipsisWidth;
        if (availableWidth <= 0) return "...";

        for (int i = text.Length - 1; i >= 0; i--)
        {
            string subText = text.Substring(i);
            if (TextRenderer.MeasureText(subText, font).Width <= availableWidth)
            {
                return "..." + subText;
            }
        }
        return "...";
    }
}

// 配套列类,方便设计器添加
public class DataGridViewLeftTruncatedTextBoxColumn : DataGridViewColumn
{
    public DataGridViewLeftTruncatedTextBoxColumn()
    {
        CellTemplate = new DataGridViewLeftTruncatedTextBoxCell();
    }
}

使用时,可直接在设计器中添加DataGridViewLeftTruncatedTextBoxColumn,或通过代码创建:

dataGridView1.Columns.Add(new DataGridViewLeftTruncatedTextBoxColumn() 
{ 
    Name = "TruncatedCol", 
    HeaderText = "左侧截断列",
    DefaultCellStyle = new DataGridViewCellStyle() { Alignment = DataGridViewContentAlignment.MiddleRight }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 02:22:44