Parveen Kumar
Parveen Kumar

Reputation: 449

C# DataGridView Display image and text in same cell

I have a requirement where I need to add image and text to same column dynamically. I have followed many examples but none of them is working. Referred to following as well but getting cast error while referring to above article. Unable to cast object of type System.Windows.Forms.DataGridViewImageCell to type DataGridViewCustom.TextAndImageCell.

http://akhaliq.com/?p=82

Can somebody help on this?

Upvotes: 4

Views: 19361

Answers (4)

Andrea86
Andrea86

Reputation: 159

You also have to handle the case when you change the row height at runtime because the image remains aligned to the cell top.

To avoid this you can update Location:

    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);

            // ====> Recalculate Location to have a Middle alignment
            int verticalPosition = cellBounds.Y + ( (cellBounds.Height/2) - (this.Image.Height/2) );
            cellBounds.Location = new Point(cellBounds.X, verticalPosition);

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

            graphics.EndContainer(container);

        }
    }

Upvotes: 2

Niraj Trivedi
Niraj Trivedi

Reputation: 2890

You can you convert DataGridView cell dynamically to DataGridViewTextBoxCell() and display text value to that column. below is code sample that gives you some basic idea.

private void DisplayButton_Click(object sender, EventArgs e)
{
    dataGridView1.Rows[3].Cells["ImageCol"] = new DataGridViewTextBoxCell();
    dataGridView1.Rows[3].Cells["ImageCol"].Value = "Hello..";  
}

Upvotes: -1

this is better

                graphics.DrawImageUnscaled(this.Image, new Point(cellBounds.Location.X + 2, cellBounds.Location.Y + ((cellBounds.Height-this.Image.Height)/2)));

Upvotes: -1

Al-3sli
Al-3sli

Reputation: 2181

I didn't find any code on the link you share, i'll give you code i used before.

1- First create new class name it TextAndImageColumn.cs :

This is the class 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; }
    }
}
}

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

3- Add a image list with the user control with 2 different Images( 16 x 16) .png files.

4- 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];
     }

5- 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();
    }

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

Upvotes: 7

Related Questions