如何在datagridview列标题中显示图像?

在运行时,我将一个DataGridView添加到Windows窗体。 最后一列是DataGridViewImageColumn

 Dim InfoIconColumn As New DataGridViewImageColumn MyDataGridView.Columns.Insert(MyDataGridView.Columns.Count, InfoIconColumn) 

添加以下代码将使我的信息图标(位图)显示在每个列单元格中,但不显示在列标题中:

 Dim InfoIcon As New Bitmap("C:\MyPath\InfoIcon.bmp") InfoIconColumn.Image = InfoIcon 

此外,值得注意的是,图像在细胞中“完美”显示,即它的大小正确以适合细胞。

但是,我找不到将相同图像添加到列标题单元格的方法。 经过一些谷歌搜索后,我使用下面的代码将图像放在标题单元格中,但给我留下了两个问题:

  1. 图像没有像添加到列单元格时那样对列标题单元“自动resize”。 图像略大且模糊。
  2. 通过使用_CellPainting事件减慢性能,即当hover在DataGridView以突出显示所选行时,突出显示落后于放置鼠标的位置。

这是代码:

 Private Sub MyDataGridView_CellPainting(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellPaintingEventArgs) Handles MyDataGridView.CellPainting Dim InfoIcon As Image = Image.FromFile("C:\MyPath\InfoIcon.bmp") If e.RowIndex = -1 AndAlso e.ColumnIndex = MyDataGridView.Columns.Count - 1 Then e.Paint(e.CellBounds, DataGridViewPaintParts.All And Not DataGridViewPaintParts.ContentForeground) e.Graphics.DrawImage(InfoIcon, e.CellBounds) e.Handled = True End If End Sub 

有没有人知道解决我的问题的方法,并在运行时获得一个大小,清晰的图像到DataGridViewImageColumn标题单元?

一种方法是使用CellsPainting事件为特定的标题单元格绘制位图。 假设位图在图像列表中,这是执行此操作的代码。

 //this.images is an ImageList with your bitmaps void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e) { if (e.ColumnIndex == 1 && e.RowIndex == -1) { e.PaintBackground(e.ClipBounds, false); Point pt = e.CellBounds.Location; // where you want the bitmap in the cell int offset = (e.CellBounds.Width - this.images.ImageSize.Width) / 2; pt.X += offset; pt.Y += 1; this.images.Draw(e.Graphics, pt, 0); e.Handled = true; } } 

我需要一些更复杂的东西 – 在列对齐方面的某些列标题中的文本前面添加图像。

您需要实现自己的System.Windows.Forms.DataGridViewColumnHeaderCell并替换ColumnHeaderCell

 // Create header and set up image YourDataGridViewColumnHeaderCell headerCell = new YourDataGridViewColumnHeaderCell(); headerCell.Image = something; // Create column DataGridViewColumn yourColumn = new DataGridViewTextBoxColumn(); // ... yourColumn.ColumnHeaderCell = new headerCell; 

现在有趣的部分(列标题的实现):

 class YourDataGridViewColumnHeaderCell : System.Windows.Forms.DataGridViewColumnHeaderCell { // Set up image as you want System.Drawing.Image Image { get; set; } } 

现在我们要添加Paint()方法。 唯一棘手的部分是使用System.Windows.Forms.DataGridViewPaintParts

 protected override void Paint( Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates dataGridViewElementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts ) { // Outside header or without an image, use default painting if ((rowIndex != -1) || (Image == null)) { base.Paint( graphics, clipBounds, cellBounds, rowIndex, dataGridViewElementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts ); return; } // Borders, background, focus selection can remain the same // But Foreground will have different image base.Paint( graphics, clipBounds, cellBounds, rowIndex, dataGridViewElementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts & ~DataGridViewPaintParts.ContentForeground ); // Repainting of content background (that's where we want to place our image) if ((paintParts & DataGridViewPaintParts.ContentBackground) != DataGridViewPaintParts.None) { // +4 is hardcoded margin Point bounds = new Point( cellBounds.X + 4, cellBounds.Y ); // Handle vertical alignment correctly switch (cellStyle.Alignment) { // Top case DataGridViewContentAlignment.TopLeft: case DataGridViewContentAlignment.TopCenter: case DataGridViewContentAlignment.TopRight: // Already set break; // Middle case DataGridViewContentAlignment.MiddleLeft: case DataGridViewContentAlignment.MiddleCenter: case DataGridViewContentAlignment.MiddleRight: bounds.Y = cellBounds.Y + (cellBounds.Height - Image.Height) / 2; break; // Bottom case DataGridViewContentAlignment.BottomLeft: case DataGridViewContentAlignment.BottomCenter: case DataGridViewContentAlignment.BottomRight: bounds.Y = cellBounds.Y + (cellBounds.Height - Image.Height); break; } graphics.DrawImage( Image, bounds ); } // Foreground should be shifted by left image margin + image.width + right // image margin and of course target spot should be a bit smaller if ((paintParts & DataGridViewPaintParts.ContentForeground) != DataGridViewPaintParts.None) { Rectangle newCellBounds = new Rectangle( cellBounds.X + 4 + Image.Width + 4, cellBounds.Y, cellBounds.Width - Image.Width - 8, cellBounds.Height ); base.Paint( graphics, clipBounds, newCellBounds, rowIndex, dataGridViewElementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, DataGridViewPaintParts.ContentForeground ); } } 

如果要将AutoSizeColumnsMode设置为DataGridViewAutoSizeColumnsMode.ColumnHeaders (因此您将自动调整图像文本),则需要覆盖DataGridViewColumnHeaderCell.GetPreferredSize 。 我通过使用基本实现并向其添加Image.Width + Padding来完成此操作。

 protected override Size GetPreferredSize( Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex,Size constraintSize ) { // Load up original image Size original = base.GetPreferredSize( graphics, cellStyle, rowIndex, constraintSize ); // Ensure the image is set and that we are working on header if ((rowIndex != -1) || (Image == null)) { return original; } // -1 is reserved value if (original.Width < 0) { return original; } return new Size( original.Width + Image.Width + 4, original.Height ); } 

注意 :我花了几个小时挖掘.NET源代码,直到我弄明白这一点。 希望你不必。

试试这个:

 Private Sub DataGridView1_CellPainting(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellPaintingEventArgs) Handles DataGridView1.CellPainting If e.RowIndex > -1 Then If e.ColumnIndex = -1 Then e.Paint(e.CellBounds, DataGridViewPaintParts.Focus And Not DataGridViewPaintParts.ContentForeground) DataGridView1.RowHeadersBorderStyle = DataGridViewHeaderBorderStyle.Single e.Graphics.DrawImage(IconImg, e.CellBounds) e.Handled = True 'DataGridView1.RowHeadersWidth = 100 'DataGridView1.ColumnHeadersHeight = 25 End If End If 

试试这段代码:

  Private Sub DataGridView1_CellPainting(ByVal sender As System.Object, _ ByVal e As System.Windows.Forms.DataGridViewCellPaintingEventArgs) _ Handles DataGridView1.CellPainting If e.RowIndex = -1 AndAlso e.ColumnIndex = DataGridView1.Columns.Count - 1 Then e.Paint(e.CellBounds, DataGridViewPaintParts.All And Not DataGridViewPaintParts.ContentForeground) e.Graphics.DrawImage(IconImg, e.CellBounds) e.Handled = True End If End Sub 

如果您已阅读完整文章,请执行此操作检查此链接:

http://www.authorcode.com/add-image-on-datagridview-column-header-in-vb-net/