Tuesday, September 28, 2010

How to insert image with Text in one cell of datagridview in C#

1.) Firstly create a Windpw Application in C#. 
2.) And then pick a DataGridView control into a user control.
3.) After that attach one class named "TextAndImageColumn" and paste the following code




using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

namespace TradeGrid
{
    public class TextAndImageColumn : DataGridViewTextBoxColumn
    {
        private Image imageValue;
        private Size imageSize;

        public TextAndImageColumn()
        {
            this.CellTemplate = new TextAndImageCell();
        }

        public override object Clone()
        {
            TextAndImageColumn c = base.Clone() as TextAndImageColumn;
            c.imageValue = this.imageValue;
            c.imageSize = this.imageSize;
            return c;
        }

        public Image Image
        {
            get { return this.imageValue; }
            set
            {
                if (this.Image != value)
                {
                    this.imageValue = value;
                    this.imageSize = value.Size;

                    if (this.InheritedStyle != null)
                    {
                        Padding inheritedPadding = this.InheritedStyle.Padding;
                        this.DefaultCellStyle.Padding = new Padding(imageSize.Width,
                     inheritedPadding.Top, inheritedPadding.Right,
                     inheritedPadding.Bottom);
                    }
                }
            }
        }
        private TextAndImageCell TextAndImageCellTemplate
        {
            get { return this.CellTemplate as TextAndImageCell; }
        }
        internal Size ImageSize
        {
            get { return imageSize; }
        }
    }

    public class TextAndImageCell : DataGridViewTextBoxCell
    {
        private Image imageValue;
        private Size imageSize;

        public override object Clone()
        {
            TextAndImageCell c = base.Clone() as TextAndImageCell;
            c.imageValue = this.imageValue;
            c.imageSize = this.imageSize;
            return c;
        }

        public Image Image
        {
            get
            {
                if (this.OwningColumn == null ||
            this.OwningTextAndImageColumn == null)
                {

                    return imageValue;
                }
                else if (this.imageValue != null)
                {
                    return this.imageValue;
                }
                else
                {
                    return this.OwningTextAndImageColumn.Image;
                }
            }
            set
            {
                if (this.imageValue != value)
                {
                    this.imageValue = value;
                    this.imageSize = value.Size;

                    Padding inheritedPadding = this.InheritedStyle.Padding;
                    this.Style.Padding = new Padding(imageSize.Width,
                    inheritedPadding.Top, inheritedPadding.Right,
                    inheritedPadding.Bottom);
                }
            }
        }

        protected override void Paint(Graphics graphics, Rectangle clipBounds,
        Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState,
        object value, object formattedValue, string errorText,
        DataGridViewCellStyle cellStyle,
        DataGridViewAdvancedBorderStyle advancedBorderStyle,
        DataGridViewPaintParts paintParts)
        {
            // Paint the base content
            base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState,
               value, formattedValue, errorText, cellStyle,
               advancedBorderStyle, paintParts);

            if (this.Image != null)
            {
                // Draw the image clipped to the cell.
                System.Drawing.Drawing2D.GraphicsContainer container =
                graphics.BeginContainer();

                graphics.SetClip(cellBounds);
                graphics.DrawImageUnscaled(this.Image, cellBounds.Location);

                graphics.EndContainer(container);
            }
        }

        private TextAndImageColumn OwningTextAndImageColumn
        {
            get { return this.OwningColumn as TextAndImageColumn; }
        }
    }
}

4.) after that you click on the Edit column of Datagridview (on Design mode) and 
change the Column Type : DataGridViewTextBoxColumn     To  Column Type: TextAndImageColumn

5.) Add a image list with the user control with 2 different Images( 16 x 16) .png files.
6.)And then add a method to display the image and Text value in one cell of DataGridView

       public void ImageRowDisplay()
        {
            ((TextAndImageCell)_TradeGrid.Rows[0].Cells[0]).Image = (Image)imageList1.Images[1];
         }
7.)And then add data on the grid rows with Text and Image cell on button Click event.

        private void btnInsertData_Click(object sender, EventArgs e)
        {
            //Code to insert rows on the grid.
             ImageRowDisplay();
        }


14 comments:

  1. Its really a Helpful and a good job .As i also have the same problem,but can we get a sample solution to have clear knowledge?
    my email is tribhuwan.kushwaha@gmail.com

    ReplyDelete
  2. Very good Work.
    If you could add it to codeproject, many more could be benefited.
    Thanks for the post.

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. Great Job
    Thanks a lot for sharing this solution

    ReplyDelete
  5. Hello, I am having problems in changing the column type in Design mode. Can anyone please help explain? I think I am missing something. Your help is very much appreciated. Thanks!

    ReplyDelete
    Replies
    1. This comment has been removed by the author.

      Delete
    2. It is possible to change the column type(TextAndImageColumn) in code(maybe WinForm code). Not design mode.

      Example)
      In your winform code...

      DataGridView dataGridView; // It is your datagridview control object
      TextAndImageColumn textNimageCol = new TextAndImageColumn();
      textNimageCol .Name = "text";
      textNimageCol .HeaderText = "text";
      dataGridView.Columns.Add(textNimageCol);

      Delete
  6. error : Please help me

    The name '_TradeGrid' does not exist in the current context

    ReplyDelete
  7. Everything turned out great, thank you very much!

    One drawback - the Image is pressed to the top of the row, although alignement for cell in the DataGridCellStyle is set to MiddleCenter

    It looks like it only affects on text, but not on Image.
    Can you tell me how to fix it, I can't do it on my own?

    ReplyDelete
  8. Canceling the previous comment. Did it myself

    ReplyDelete
  9. DataGridCellStyle to MiddleCenter:
    // Draw the image clipped to the cell.
    System.Drawing.Drawing2D.GraphicsContainer container =
    graphics.BeginContainer();

    graphics.SetClip(cellBounds);

    //change the alligment
    Rectangle rec = cellBounds;
    rec.Width = cellBounds.Width;
    rec.Height = cellBounds.Height;
    rec.X = cellBounds.X + 5; //altern. can center on half bounds
    rec.Y = cellBounds.Y + (cellBounds.Height /2) - (this.Image.Height / 2);

    graphics.DrawImageUnscaled(this.Image, rec);

    graphics.EndContainer(container);

    ReplyDelete