[英]How to display an image in a datagridview column header?
在运行时,我将一个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
此外,值得注意的是,图像在细胞中“完美”显示,即它的大小正确以适合细胞。
但是,我找不到将相同图像添加到列标题单元格的方法。 经过一些谷歌搜索我使用下面的代码将图像放在标题单元格中,但给我留下了两个问题:
_CellPainting
事件减慢性能,即当悬停在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
事件为特定的标题单元格绘制位图。 下面是代码,做这个假设位图是一个imagelist
。
//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/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.