WinForms DataGridView列宽不足时如何隐藏文本左侧内容?
在.NET 6 WinForms DataGridView实现左侧截断文本(...DEFG)
默认情况下,DataGridView的文本截断逻辑是从右侧截断,仅设置MiddleRight对齐只会调整文本在单元格内的位置,不会改变截断方向。要实现左侧截断(开头隐藏、末尾保留加省略号),常用两种方案:
方法一:通过CellPainting事件自定义绘制
这是无需额外控件的快速实现方式,直接在已有DataGridView上绑定事件处理:
- 给DataGridView绑定
CellPainting事件 - 在事件逻辑中跳过标题行/空单元格,计算文本宽度,判断是否需要截断
- 手动绘制单元格背景、边框,再绘制左侧截断后的文本
示例代码:
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中复用该功能,建议封装自定义单元格:
- 继承
DataGridViewTextBoxCell并重写Paint方法,内置左侧截断逻辑 - (可选)创建对应列类,方便在设计器中直接使用
示例代码:
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
相关产品推荐
相关产品推荐

