Search code examples
c#winformsdatagridviewdatagridviewimagecolumn

How to use DataGridViewImageColumn to display images using zoom and also keeping the aspect ratio?


My code

Building the column

IconColumn = new DataGridViewImageColumn()
{
    Name = "Icon",
    HeaderText = "Icon",
    SortMode = DataGridViewColumnSortMode.NotSortable,
    Width = 50,
    ImageLayout = DataGridViewImageCellLayout.Stretch,
    Resizable = DataGridViewTriState.False
};
IconColumn.DefaultCellStyle.NullValue = null;
IconColumn.CellTemplate = new ClockDataGridViewIconCell();

Setting an icon

float maxHeight = 200;
float maxWidth = 200;

var r = new Rectangle(0,
    0,
    (int)Math.Round(maxWidth),
    (int)Math.Round(maxHeight)
);
MyClockData.Icon = Utils.ResizeToFitBoundingBox(
    new Bitmap(fd.FileName),
    r);

The ResizeToFitBoundingBox method

internal static Bitmap ResizeToFitBoundingBox(Image image, in Rectangle box)
{
    float maxHeight = box.Width;
    float maxWidth = box.Height;

    float x = Math.Min(maxWidth / image.Width,
        maxHeight / image.Height);

    float newW = (float)image.Width * x;
    float newH = (float)image.Height * x;

    var bmp = new Bitmap((int)Math.Round(maxWidth),
        (int)Math.Round(maxHeight));
    bmp.MakeTransparent();
    using (Graphics gr = Graphics.FromImage(bmp))
    {
        gr.DrawImage(image, (bmp.Width - newW) / 2,
            (bmp.Height - newH) / 2, newW, newH);
    }

    return bmp;
}

Example icon

full-sized-icon

I have tried all the 4 possible values for DataGridViewImageColumn.ImageLayout and the cell looks the same:

  1. Normal

normal

  1. Not Set

not-set

  1. Stretch

stretch

  1. Zoom

zoom

None of them Works for what I wish. The official documentation is here. I would like the same behaviour as Forms.ImageLayout.Zoom.

Note: I use .NET Framework v4.6.1.


Solution

  • I solved the problem by adding this line:

    IconColumn.ImageLayout = DataGridViewImageCellLayout.Zoom;
    

    after each statement which adds or updates an icon in the DataGridView.

    It seems that setting this property to the same value as before repaints the icons in the column in the way the value of the property suggests.