DataGridView Image Columns

I have been pulling my hair out on this one and decided it was time to post it here after Googling for countless hours without finding an answer to my problem.

I have a simple databound datagridview that I am trying to display an image on a cell by cell basis based on the cell value (stop, started, finished) etc.. The values are int values and so far I have been able to get it to work but I have noticed lots of flickering while using the grid and lots of mismatched images being displayed for the underlying cell value. Any help would be much appreciated...

private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)

{

if (e.ColumnIndex == 2)

{

DataGridViewRow row = this.dataGridView1.Rows[e.RowIndex];

DataGridViewCell cell = row.Cells[1];

if ((int)cell.Value == 2)

{

DataGridViewImageColumn col = (DataGridViewImageColumn)this.dataGridView1.Columns[2];

col.Image = Data_Grids.Properties.Resources.ProcessRestartedS.ToBitmap();

}

else

{

DataGridViewImageColumn col = (DataGridViewImageColumn)this.dataGridView1.Columns[2];

col.Image = Data_Grids.Properties.Resources.ProcessRunningS.ToBitmap();

}

}

}

 



Answer this question

DataGridView Image Columns

  • OwenG

     

    So the only way to achieve this is by overriding the On_Paint event Seems like I was going in the right direction but I guess not.....

     

    Thanks for the reply.

     

     


  • LA_Zi

    Check out the custom DGV "rating" column here: http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=179595&SiteID=1 < xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

     

    In the sample I've taken the image column but my data is an integer, so I convert the integer to an image.

     

    -mark

    DataGridView Program Manager

    Microsoft

    This post is provided "as-is"

     

     


  • Felipe Levin

    Could you post an example
  • Jimmy Bogard


    Thanx MM,

    I was using the cell formating event, but I was trying to draw the image in a column that was bound to a database with datatype = string. I don't want to create a new column cause the image columns are always the first, independently of the order you create or insert it in the datagridview (it's strange, I've made some experiments and couldn't change the order for an image column, found many posts saying it isn't possible).

    The way that worked better for me was use the CellPainting instead of CellFormating and draw the image I wanted. This way it wasn't necessary to create a new column neither to use a custom made cell type.


    Thank you,
    Augusto

  • Alex1123123

    hey mark,

    you are getting system.drawing.Image because you are not using the cellformatting

    here is the VB code for it which i use in my datagrid to display images.

    Private Sub dgvEditList_CellFormatting(ByVal sender As Object, ByVal e As DataGridViewCellFormattingEventArgs) Handles dgvEditList.CellFormatting

    ' Check if it's the Image column.

    If dgvEditList.Columns(e.ColumnIndex).Name = "Thumbnail" And _

    dgvEditList.Rows(e.RowIndex).Cells("Thumbnail").Value IsNot Nothing Then

    ' Set the value based on the hidden ProductImage column.

    ' Dim fileName As String = Application.StartupPath & "\" & dgvEditList.Rows(e.RowIndex).Cells("Thumbnail").Value.ToString()

    Dim fileName As String = dgvEditList.Rows(e.RowIndex).Cells("Thumbnail").Value.ToString()

    If File.Exists(fileName) Then

    e.Value = Image.FromFile(fileName)

    End If

    End If

    End Sub

    Hope this helps

    MM


  • Thomas Roethlisberger

    Hi Mark,

    I'm working with a databound column and when I set the e.Value to an image, the column is displayed as "System.Drawing.Image", not the image I've set.

    Is there another solution

    Thanks,

  • enki

     

    So if I were to use an unbound column to do this where would you recommend that I perform some sort of a switch against the databound column to assign the appropriate image to the unbound column Currently the code I have will work however if the datagrid attempts to repaint during a scroll, etc.. the grid becomes ofuscated and the CPU on my machine spikes.

     Thanks again for your help on this.... Still learning everything new about the datagridview...


  • tamccann

    This appears to work and doesn't spike the CPU... If there is a better way please post an example. Otherwise thanks for all of the help on this one. It's funny how simple things are once you figure them out.

     

    private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)

    {

    if (e.ColumnIndex == 1)

    {

    DataGridViewRow row = this.dataGridView1.Rows[e.RowIndex];

    DataGridViewCell cell = row.Cells[3];

    if ((int)e.Value == 2)

    {

    cell.Value = Data_Grids.Properties.Resources.ProcessStoppedS;

    }

    else

    {

    cell.Value = Data_Grids.Properties.Resources.ProcessRestartedS;

    }

    }

    }


  • murali-indian

    You can do this in a bound column just handle the CellFormatting event and set the e.Value to your custom image based upon the cell's value. Again, you don't want to set the column's image value, but instead set the cell's image value, otherwise you'll see perf issues.< xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

     

    -mark

    DataGridView Program Manager

    Microsoft

    This post is provided "as-is"

     

     


  • Destroy89

    I found a very simple solution that operates on a column containing data-bound boolean values (no doubt this could be modified to any underlying value type). Grid is bound to a datatable via a BindingSource object:

    void DataGridView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)

    {

    if (this.Columns[e.ColumnIndex] is DataGridViewImageColumn)

    {

    e.Value = ((bool)e.Value) Properties.Resources.bullet_black: Properties.Resources.bullet_transparent;

    }

    }

    No performance problems, no hidden columns for logic either, the cells seem to keep their underlying data values but use the images set in e.Value for display.


  • Jsmith4892002

    Using CellPaint isn't the only way, doing what you did does work and should work fine. The only problem I see is if the ImageColumn is actually databound to a database field that has integer values -- this could cause problems. The reason is that the ImageColumn accesses the underlying value and could cause display problems when it attempts to use that int value as an image. CellFormatting only is called when the image column is attempting to format the value for display.

    EDIT: look at your code above a bit more -- you shouldn't set the column's image value in the CellFormatting event -- you should set the e.Value property in the CellFormatting event args. I think that will fix up the problems you are seeing.

    -mark
    DataGridView Program Manager
    Microsoft
    This post is provided "as-is"

     


  • stebe000

    I'd recommend changing your


    cell.Value = Data_Grids.Properties.Resources.ProcessStoppedS;
     
    line to

    e.Value = Data_Grids.Properties.Resources.ProcessStoppedS;
     
    Otherwise you are actually changing the datatype of the cell from holding an integer to holding an image. In fact, I think this errors out if your image column is databound. If your image column is not databound, then you are probably fine doing this.< xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

     

    -mark

    DataGridView Program Manager

    Microsoft

    This post is provided "as-is"

     


  • DataGridView Image Columns