Click here to Skip to main content
13,198,467 members (64,594 online)
Click here to Skip to main content
Add your own
alternative version


172 bookmarked
Posted 10 Oct 2010

How to Create ProgressBar Column in DataGridView

, 15 Nov 2010
Rate this:
Please Sign up or sign in to vote.
An article on how to create a ProgressBar Column in DataGridView


A couple of days ago, I was working on a program that allows users to upload multiple files on a server. I realized it would be nice to show progress of upload for every file individually. I tried to find a way how to solve this. After hours of “Googling” I found some solutions, how to show progress bar in DataGridView object so I decided to create my own custom progress bar column. Articles I found served as a guide for me and I have picked up same ideas, how to customize DataGridView columns. I have implemented some functionality that I will describe later.


DataGridView control provides several column types, enabling users to enter and edit values in a variety of ways. Sometimes these column types do not meet needs, but that’s not a problem because you can create your own column types that can host controls you need. When you want to create your own column type, you must define some classes derived from DataGridViewColumn and DataGridViewCell.

In this short example, I will show you how to create a progress bar column. This example does not directly insert progress bar control into a cell, it only draws a rectangle which looks like a progress bar.

To do this, you must define classes that derive from DataGridViewColumn and DataGridViewImageCell. (You can also derive from DataGridViewCell which is the base type of all cells directly, but in this case is much more suitable to derive from DataGridViewImageCell, because we will use some graphical operations.)

Main Steps

As I mentioned earlier, two classes must be created. The first class I have created is DataGridViewProgressColumn which derives from DataGridViewImageColumn. This class creates a custom column for hosting progress bar cells and overrides property CellTemplate.

public class DataGridViewProgressColumn : DataGridViewImageColumn
        . . . 

        public override DataGridViewCell CellTemplate
                return base.CellTemplate;
                if (value != null &&
                    throw new InvalidCastException("Must be a DataGridViewProgressCell");
                base.CellTemplate = value;

       . . .

The second class I have created is DataGridViewProgressBarCell. This class creates a custom cell for hosting a progress bar. This class derives from DataGridViewImageCell.

When developing a custom cell type, it is also critical to check if some virtual methods need to be overridden. In this example, two methods need to be overridden: Clone() method and Paint() method.

Paint() Method

In order to draw the content of the cell in the way we wanted, we must overload the paint method. This method is a critical one for any cell type. It is responsible for painting a cell. It sets various properties and is responsible for calling Graphics.FillRectangle(…) and Graphics.DrawString(…) methods which draw progress bar and write a text.

protected override void Paint(System.Drawing.Graphics g, 
    System.Drawing.Rectangle clipBounds, 
    System.Drawing.Rectangle cellBounds, 
    int rowIndex, 
    DataGridViewElementStates cellState, 
    object value, object formattedValue, 
    string errorText, 
    DataGridViewCellStyle cellStyle, 
    DataGridViewAdvancedBorderStyle advancedBorderStyle, 
    DataGridViewPaintParts paintParts)
    if (Convert.ToInt16(value) == 0 || value == null)
        value = 0;
    int progressVal = Convert.ToInt32(value);
    // Need to convert to float before division; 
    //otherwise C# returns int which is 0 for anything but 100%.
    float percentage = ((float)progressVal / 100.0f); 
    Brush backColorBrush = new SolidBrush(cellStyle.BackColor);
    Brush foreColorBrush = new SolidBrush(cellStyle.ForeColor);
    // Draws the cell grid
    base.Paint(g, clipBounds, cellBounds, rowIndex, 
        cellState, value, formattedValue, errorText, 
        cellStyle, advancedBorderStyle, 
	(paintParts & ~DataGridViewPaintParts.ContentForeground));
    float posX = cellBounds.X;
    float posY = cellBounds.Y;
    float textWidth = TextRenderer.MeasureText
	(progressVal.ToString() + "%", cellStyle.Font).Width;
    float textHeight = TextRenderer.MeasureText
	(progressVal.ToString() + "%", cellStyle.Font).Height;
    //evaluating text position according to selected alignment
    //default text alignment is TopLeft
    //variables posX and posY determine position of progress value text (percentage+"%")
    switch (cellStyle.Alignment)
        case DataGridViewContentAlignment.BottomCenter:
            posX = cellBounds.X + (cellBounds.Width / 2) - textWidth / 2;
            posY = cellBounds.Y + cellBounds.Height - textHeight;
        case DataGridViewContentAlignment.BottomLeft:
            posX = cellBounds.X;
            posY = cellBounds.Y + cellBounds.Height - textHeight;
        case DataGridViewContentAlignment.BottomRight:
            posX = cellBounds.X + cellBounds.Width - textWidth;
            posY = cellBounds.Y + cellBounds.Height - textHeight;
        case DataGridViewContentAlignment.MiddleCenter:
            posX = cellBounds.X + (cellBounds.Width / 2) - textWidth / 2;
            posY = cellBounds.Y + (cellBounds.Height / 2) - textHeight / 2;
        case DataGridViewContentAlignment.MiddleLeft:
            posX = cellBounds.X;
            posY = cellBounds.Y + (cellBounds.Height / 2) - textHeight / 2;
        case DataGridViewContentAlignment.MiddleRight:
            posX = cellBounds.X + cellBounds.Width - textWidth;
            posY = cellBounds.Y + (cellBounds.Height / 2) - textHeight / 2;
        case DataGridViewContentAlignment.TopCenter:
            posX = cellBounds.X + (cellBounds.Width / 2) - textWidth / 2;
            posY = cellBounds.Y;
        case DataGridViewContentAlignment.TopLeft:
            posX = cellBounds.X;
            posY = cellBounds.Y;
        case DataGridViewContentAlignment.TopRight:
            posX = cellBounds.X + cellBounds.Width - textWidth;
            posY = cellBounds.Y;
    if (percentage >= 0.0)
        // Draw the progress 
        g.FillRectangle(new SolidBrush(_ProgressBarColor), cellBounds.X + 2, 
            cellBounds.Y + 2, Convert.ToInt32((percentage * cellBounds.Width * 0.8)), 
            cellBounds.Height / 1 - 5);
        //Draw text
        g.DrawString(progressVal.ToString() + "%", 
		cellStyle.Font, foreColorBrush, posX, posY);
        //if percentage is negative, we don't want to draw progress bar
        //we want only text
        if (this.DataGridView.CurrentRow.Index == rowIndex)
            g.DrawString(progressVal.ToString() + "%", cellStyle.Font, 
                new SolidBrush(cellStyle.SelectionForeColor), posX, posX);
            g.DrawString(progressVal.ToString() + "%", cellStyle.Font, 
                foreColorBrush,posX, posY);

This method is also responsible for correct rendering of text according to alignment selected by user. This alignment can be selected in CellStyle Builder Window.

The Clone() Method

The DataGridViewImageCell derives from DataGridViewCell class that implements the ICloneable interface. Each custom cell type typically needs to override the Clone() method to copy its custom properties. Cells are cloneable because a particular cell instance can be used for multiple rows in the grid. This is the case when the cell belongs to a shared row. When a row gets unshared, its cells need to be cloned. Following is the implementation for the Clone() method:

public override object Clone()
    DataGridViewProgressCell dataGridViewCell = base.Clone() as DataGridViewProgressCell;
    if (dataGridViewCell != null)
        dataGridViewCell.ProgressBarColor = this.ProgressBarColor;
    return dataGridViewCell;

ProgressBarColor Property

I have created a new property called ProgressBarColor, which sets color of rendered progress bar. This property must be implemented in both classes (DataGridViewProgressBarCell and DataGridViewProgressBarColumn). In DataGridViewProgressBarColumn class, this method sets ProgressBarColor property of CellTemplate (which must be casted as DataGridViewProgressCell). ProgressBarColor value of CellTemplate is next passed into _progressBarColor variable of DataGridViewProgressBarCell class. _progressBarColor variable is used in Paint(…) method. Here is an implementation of ProgressBarColor property:

public Color ProgressBarColor
    get {
        if (this.ProgressBarCellTemplate == null)
            throw new InvalidOperationException
		("Operation cannot be completed because this DataGridViewColumn 
		does not have a CellTemplate.");
        return this.ProgressBarCellTemplate.ProgressBarColor;            
    set {
        if (this.ProgressBarCellTemplate == null)
            throw new InvalidOperationException
		("Operation cannot be completed because this DataGridViewColumn 
		does not have a CellTemplate.");
        this.ProgressBarCellTemplate.ProgressBarColor = value;
        if (this.DataGridView != null)
            DataGridViewRowCollection dataGridViewRows = this.DataGridView.Rows;
            int rowCount = dataGridViewRows.Count;
            for (int rowIndex = 0; rowIndex < rowCount; rowIndex++)
                DataGridViewRow dataGridViewRow = dataGridViewRows.SharedRow(rowIndex);
                DataGridViewProgressCell dataGridViewCell = 
		dataGridViewRow.Cells[this.Index] as DataGridViewProgressCell;
                if (dataGridViewCell != null)
                    dataGridViewCell.SetProgressBarColor(rowIndex, value);

As I mentioned earlier, when we want to pass ProgressBarColor value into CellTemplate, we must first get this CellTemplate. We can get CellTemplate from ProgressBarCellTemplate property of DataGridProgressColumn class. When we get this, we can easily set ProgressBarColor property of CellTemplate.

Using the Code

I have created a simple project called ProgressBarColumn. In this project, I have included one form named frmMain containing DataGridView with 2 columns. The first column is of DataGridViewTextBoxColumn Type and the second is DataGridViewProgressColumn type. In this project, I show you how to load data into DataGridView and how this grid renders DataGridViewProgressColumn.


  • 10 Oct 2010 - Original version posted


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Kanasz Robert
Architect The Staffing Edge & Marwin Cassovia Soft
Slovakia Slovakia
My name is Robert Kanasz and I have been working with ASP.NET, WinForms and C# for several years.
MCSD - Web Applications
MCSE - Data Platform
MCPD - ASP.NET Developer 3.5
- Web Developer 4
MCITP - Database Administrator 2008
- Database Developer 2008
MCSA - SQL Server 2012
MCTS - .NET Framework 3.5, ASP.NET Applications
- SQL Server 2008, Database Development
- SQL Server 2008, Implementation and Maintenance
- .NET Framework 4, Data Access
- .NET Framework 4, Service Communication Applications
- .NET Framework 4, Web Applications
MS - Programming in HTML5 with JavaScript and CSS3 Specialist

Open source projects: DBScripter - Library for scripting SQL Server database objects

Please, do not forget vote

You may also be interested in...


Comments and Discussions

GeneralMy vote of 5 Pin
jokocc23-Jan-17 19:26
memberjokocc23-Jan-17 19:26 
Questionwhy the cell can not be 100% filled Pin
Member 1215454023-Dec-15 16:21
memberMember 1215454023-Dec-15 16:21 
AnswerRe: why the cell can not be 100% filled Pin
Daniel Leykauf1-Feb-16 5:52
memberDaniel Leykauf1-Feb-16 5:52 
QuestionOwn text instead % value Pin
Member 1013821618-Jun-15 21:48
memberMember 1013821618-Jun-15 21:48 
QuestionDocking In Splitter Container - Resize Pin
stixoffire31-Mar-15 10:10
memberstixoffire31-Mar-15 10:10 
QuestionProgress and cell width Pin
GeorgeStevenson17-Jul-14 3:28
memberGeorgeStevenson17-Jul-14 3:28 
AnswerRe: Progress and cell width Pin
GeorgeStevenson17-Jul-14 22:23
memberGeorgeStevenson17-Jul-14 22:23 
AnswerThanks Pin
Serdar Gökcen17-Sep-13 0:27
memberSerdar Gökcen17-Sep-13 0:27 
GeneralRe: Thanks Pin
Kanasz Robert21-Oct-13 2:17
mvpKanasz Robert21-Oct-13 2:17 
GeneralMy vote of 4 Pin
Member 1014993911-Jul-13 6:08
memberMember 1014993911-Jul-13 6:08 
Took a minute to get it converted to Visual Basic for my app, but it works as described. Thank you for a nice addition to my program. Very much appreciated.
GeneralRe: My vote of 4 Pin
Kanasz Robert3-Sep-13 3:46
mvpKanasz Robert3-Sep-13 3:46 
GeneralMy vote of 5 Pin
Mazen el Senih29-Mar-13 5:09
memberMazen el Senih29-Mar-13 5:09 
GeneralRe: My vote of 5 Pin
Kanasz Robert29-Mar-13 5:23
mvpKanasz Robert29-Mar-13 5:23 
QuestionGood Pin
xmaster123_212-Mar-13 23:52
memberxmaster123_212-Mar-13 23:52 
AnswerRe: Good Pin
Kanasz Robert13-Mar-13 3:13
mvpKanasz Robert13-Mar-13 3:13 
GeneralMy vote of 5 Pin
rxc555557-Mar-13 17:01
memberrxc555557-Mar-13 17:01 
GeneralRe: My vote of 5 Pin
Kanasz Robert7-Mar-13 22:45
mvpKanasz Robert7-Mar-13 22:45 
GeneralMy vote of 5 Pin
gaga blues28-Nov-12 19:24
membergaga blues28-Nov-12 19:24 
GeneralRe: My vote of 5 Pin
Kanasz Robert28-Nov-12 23:02
mvpKanasz Robert28-Nov-12 23:02 
Questionnice Pin
strucker_luc18-Nov-12 3:12
memberstrucker_luc18-Nov-12 3:12 
AnswerRe: nice Pin
Kanasz Robert18-Nov-12 3:22
mvpKanasz Robert18-Nov-12 3:22 
GeneralMy vote of 4 Pin
ravithejag8-Nov-12 22:53
memberravithejag8-Nov-12 22:53 
GeneralRe: My vote of 4 Pin
Kanasz Robert9-Nov-12 2:02
mvpKanasz Robert9-Nov-12 2:02 
QuestionInteresting article and very helpful Pin
kr1234564-Nov-12 3:53
memberkr1234564-Nov-12 3:53 
AnswerRe: Interesting article and very helpful Pin
Kanasz Robert4-Nov-12 4:05
mvpKanasz Robert4-Nov-12 4:05 
GeneralMy vote of 5 Pin
Member 14669772-Nov-12 7:49
memberMember 14669772-Nov-12 7:49 
GeneralRe: My vote of 5 Pin
Kanasz Robert2-Nov-12 8:18
mvpKanasz Robert2-Nov-12 8:18 
Questionhelpful Pin
superdevX151-Nov-12 6:48
membersuperdevX151-Nov-12 6:48 
AnswerRe: helpful Pin
Kanasz Robert1-Nov-12 6:56
mvpKanasz Robert1-Nov-12 6:56 
Questiongot my 5 Pin
hakon12331-Oct-12 5:27
memberhakon12331-Oct-12 5:27 
AnswerRe: got my 5 Pin
Kanasz Robert31-Oct-12 5:38
mvpKanasz Robert31-Oct-12 5:38 
QuestionExcellent Pin
memlon mulas29-Oct-12 5:12
membermemlon mulas29-Oct-12 5:12 
AnswerRe: Excellent Pin
Kanasz Robert31-Oct-12 5:25
mvpKanasz Robert31-Oct-12 5:25 
Questiongood and well written article Pin
jackhoal27-Oct-12 3:53
memberjackhoal27-Oct-12 3:53 
AnswerRe: good and well written article Pin
Kanasz Robert27-Oct-12 4:01
mvpKanasz Robert27-Oct-12 4:01 
Questionnice article Pin
robkaan27-Oct-12 3:22
memberrobkaan27-Oct-12 3:22 
AnswerRe: nice article Pin
Kanasz Robert27-Oct-12 3:32
mvpKanasz Robert27-Oct-12 3:32 
QuestionGood Pin
windevvv21-Oct-12 6:45
memberwindevvv21-Oct-12 6:45 
AnswerRe: Good Pin
Kanasz Robert21-Oct-12 7:01
mvpKanasz Robert21-Oct-12 7:01 
QuestionExcellent Pin
kaslaninovic2-Oct-12 22:42
memberkaslaninovic2-Oct-12 22:42 
AnswerRe: Excellent Pin
Kanasz Robert3-Oct-12 6:52
mvpKanasz Robert3-Oct-12 6:52 
QuestionGood job Pin
developer88123-Sep-12 2:57
memberdeveloper88123-Sep-12 2:57 
AnswerRe: Good job Pin
Kanasz Robert23-Sep-12 23:07
mvpKanasz Robert23-Sep-12 23:07 
QuestionGreat Pin
bikerius19-Sep-12 1:58
memberbikerius19-Sep-12 1:58 
AnswerRe: Great Pin
Kanasz Robert19-Sep-12 4:40
mvpKanasz Robert19-Sep-12 4:40 
QuestionGood article. Pin
pukson11-Sep-12 3:26
memberpukson11-Sep-12 3:26 
AnswerRe: Good article. Pin
Kanasz Robert11-Sep-12 3:27
mvpKanasz Robert11-Sep-12 3:27 
GeneralMy Vote of 5 Pin
RaviRanjankr31-Aug-12 8:16
mvpRaviRanjankr31-Aug-12 8:16 
GeneralRe: My Vote of 5 Pin
Kanasz Robert3-Sep-12 8:09
mvpKanasz Robert3-Sep-12 8:09 
QuestionExcellent - thanks! Pin
codeproject@zosoco.com10-Apr-12 18:15
membercodeproject@zosoco.com10-Apr-12 18:15 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.171020.1 | Last Updated 15 Nov 2010
Article Copyright 2010 by Kanasz Robert
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid