avevo bisogno cosa più complessa un po '- immagine aggiungendo davanti al testo nello alcune intestazioni di colonna rispetto all'allineamento delle colonne.
è necessario implementare il proprio System.Windows.Forms.DataGridViewColumnHeaderCell
e sostituire ColumnHeaderCell
:
// Create header and set up image
YourDataGridViewColumnHeaderCell headerCell = new YourDataGridViewColumnHeaderCell();
headerCell.Image = something;
// Create column
DataGridViewColumn yourColumn = new DataGridViewTextBoxColumn();
// ...
yourColumn.ColumnHeaderCell = new headerCell;
Ora la parte divertente (implementazione della vostra intestazione di colonna):
class YourDataGridViewColumnHeaderCell : System.Windows.Forms.DataGridViewColumnHeaderCell
{
// Set up image as you want
System.Drawing.Image Image { get; set; }
}
Ora vogliamo aggiungere Paint()
metodo. L'unica parte difficile sta funzionando 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);
}
}
Se si desidera utilizzare AutoSizeColumnsMode
set per DataGridViewAutoSizeColumnsMode.ColumnHeaders
(così si avrebbe autofit immagine e testo) è necessario sostituire DataGridViewColumnHeaderCell.GetPreferredSize
. L'ho fatto utilizzando l'implementazione di base e aggiungendo Image.Width + Padding
ad esso.
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: ho passato diverse ore a scavare in .NET sources fino a quando ho capito questo. Spero che non sia necessario.
@Lucas - Grazie per il consiglio. Darò questo tentativo e riferirò ... –
Nel caso in cui non si memorizzi l'immagine in una lista immagini, modificando la penultima 2 ° LOC; e.Graphics.DrawImage (image, pt); funziona anche –
Funziona ma come posso posizionare l'immagine dal lato del testo con un po 'di padding? – Jack