que necesitaba un poco más complejo cosa - imagen añadiendo delante del texto en algunos encabezados de columna con respecto a la alineación de columnas.
que necesita para implementar su propio System.Windows.Forms.DataGridViewColumnHeaderCell
y reemplazar ColumnHeaderCell
:
// Create header and set up image
YourDataGridViewColumnHeaderCell headerCell = new YourDataGridViewColumnHeaderCell();
headerCell.Image = something;
// Create column
DataGridViewColumn yourColumn = new DataGridViewTextBoxColumn();
// ...
yourColumn.ColumnHeaderCell = new headerCell;
Ahora la parte divertida (aplicación de la cabecera de la columna):
class YourDataGridViewColumnHeaderCell : System.Windows.Forms.DataGridViewColumnHeaderCell
{
// Set up image as you want
System.Drawing.Image Image { get; set; }
}
Ahora queremos añadir Paint()
método. La única parte difícil es trabajar con 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);
}
}
Si desea utilizar AutoSizeColumnsMode
conjunto de DataGridViewAutoSizeColumnsMode.ColumnHeaders
(lo que sería Autofit imagen y texto) que necesita para anular DataGridViewColumnHeaderCell.GetPreferredSize
. Hice esto mediante el uso de la implementación base y agregando Image.Width + Padding
a ella.
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);
}
NOTA: he pasado varias horas cavando en .NET sources hasta que me di cuenta de esto. Espero que no sea necesario.
@Lucas - Gracias por el consejo. Daré esta tratar e informar ... –
En el caso de que no almacenar la imagen en una ImageList, la modificación de la segunda pasada a LOC; e.Graphics.DrawImage (imagen, pt); también funciona –
Funciona, pero ¿cómo puedo colocar la imagen por el lado del texto con algo de relleno? – Jack