I have a column that has integer data in it, I want to display it as a progress bar in the column so the user can quickly identify lagging processes.
I just started with 2005 and it looks great but does anyone know a quick way to do this
I would also like to change the color of the progress bar based on the cells value.
I found in the data sources toolbox where I can change the column to progress bar but that does not pass through to the grid.
Thanks for ANY help with this

Sample Code: DataGridView progress bar column
Cyberjunkie
Here is an unsupported progress bar cell/column sample in VB and C#:
VB:
'---------------------------------------------------------------------
' THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
' KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
' IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
' PARTICULAR PURPOSE.
'---------------------------------------------------------------------
Imports System.Drawing
Imports System.ComponentModel
Public Class DataGridViewProgressColumn
Inherits DataGridViewImageColumn
Public Sub New()
Me.CellTemplate = New DataGridViewProgressCell
End Sub
End Class
Public Class DataGridViewProgressCell
Inherits DataGridViewImageCell
Sub New()
ValueType = Type.GetType("Integer")
End Sub
' Method required to make the Progress Cell consistent with the default Image Cell.
' The default Image Cell assumes an Image as a value, although the value of the Progress Cell is an Integer.
Protected Overrides Function GetFormattedValue( _
ByVal value As Object, _
ByVal rowIndex As Integer, _
ByRef cellStyle As DataGridViewCellStyle, _
ByVal valueTypeConverter As TypeConverter, _
ByVal formattedValueTypeConverter As TypeConverter, _
ByVal context As DataGridViewDataErrorContexts _
) As Object
Static emptyImage As Bitmap = New Bitmap(1, 1, System.Drawing.Imaging.PixelFormat.Format32bppArgb)
GetFormattedValue = emptyImage
End Function
Protected Overrides Sub Paint(ByVal g As System.Drawing.Graphics, ByVal clipBounds As System.Drawing.Rectangle, ByVal cellBounds As System.Drawing.Rectangle, ByVal rowIndex As Integer, ByVal cellState As System.Windows.Forms.DataGridViewElementStates, ByVal value As Object, ByVal formattedValue As Object, ByVal errorText As String, ByVal cellStyle As System.Windows.Forms.DataGridViewCellStyle, ByVal advancedBorderStyle As System.Windows.Forms.DataGridViewAdvancedBorderStyle, ByVal paintParts As System.Windows.Forms.DataGridViewPaintParts)
Dim progressVal As Integer = CType(value, Integer)
Dim percentage As Single = CType((progressVal / 100), Single)
Dim backBrush As Brush = New SolidBrush(cellStyle.BackColor)
Dim foreBrush As Brush = New SolidBrush(cellStyle.ForeColor)
' Call the base class method to paint the default cell appearance.
MyBase.Paint(g, clipBounds, cellBounds, rowIndex, cellState, _
value, FormattedValue, ErrorText, cellStyle, _
advancedBorderStyle, paintParts)
If percentage > 0.0 Then
' Draw the progress bar and the text
g.FillRectangle(New SolidBrush(Color.FromArgb(163, 189, 242)), cellBounds.X + 2, cellBounds.Y + 2, Convert.ToInt32((percentage * cellBounds.Width - 4)), cellBounds.Height - 4)
g.DrawString(progressVal.ToString() & "%", cellStyle.Font, foreBrush, cellBounds.X + 6, cellBounds.Y + 2)
Else
'draw the text
If Not Me.DataGridView.CurrentCell Is Nothing AndAlso Me.DataGridView.CurrentCell.RowIndex = rowIndex Then
g.DrawString(progressVal.ToString() & "%", cellStyle.Font, New SolidBrush(cellStyle.SelectionForeColor), cellBounds.X + 6, cellBounds.Y + 2)
Else
g.DrawString(progressVal.ToString() & "%", cellStyle.Font, foreBrush, cellBounds.X + 6, cellBounds.Y + 2)
End If
End If
End Sub
End Class
Here is the C# version:
//---------------------------------------------------------------------
//THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
//KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//PARTICULAR PURPOSE.
//---------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.ComponentModel;
namespace Sample
{
public class DataGridViewProgressColumn : DataGridViewImageColumn
{
public DataGridViewProgressColumn()
{
CellTemplate = new DataGridViewProgressCell();
}
}
}
namespace Sample
{
class DataGridViewProgressCell : DataGridViewImageCell
{
// Used to make custom cell consistent with a DataGridViewImageCell
static Image emptyImage;
static DataGridViewProgressCell()
{
emptyImage = new Bitmap(1, 1, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
}
public DataGridViewProgressCell()
{
this.ValueType = typeof(int);
}
// Method required to make the Progress Cell consistent with the default Image Cell.
// The default Image Cell assumes an Image as a value, although the value of the Progress Cell is an int.
protected override object GetFormattedValue(object value,
int rowIndex, ref DataGridViewCellStyle cellStyle,
TypeConverter valueTypeConverter,
TypeConverter formattedValueTypeConverter,
DataGridViewDataErrorContexts context)
{
return emptyImage;
}
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)
{
int progressVal = (int)value;
float percentage = ((float)progressVal / 100.0f); // Need to convert to float before division; otherwise C# returns int which is 0 for anything but 100%.
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));
if (percentage > 0.0)
{
// Draw the progress bar and the text
g.FillRectangle(new SolidBrush(Color.FromArgb(163, 189, 242)), cellBounds.X + 2, cellBounds.Y + 2, Convert.ToInt32((percentage * cellBounds.Width - 4)), cellBounds.Height - 4);
g.DrawString(progressVal.ToString() + "%", cellStyle.Font, foreColorBrush, cellBounds.X + 6, cellBounds.Y + 2);
}
else
{
// draw the text
if (this.DataGridView.CurrentRow.Index == rowIndex)
g.DrawString(progressVal.ToString() + "%", cellStyle.Font, new SolidBrush(cellStyle.SelectionForeColor), cellBounds.X + 6, cellBounds.Y + 2);
else
g.DrawString(progressVal.ToString() + "%", cellStyle.Font, foreColorBrush, cellBounds.X + 6, cellBounds.Y + 2);
}
}
}
}
-mark
DataGridView Program Manager
Microsoft
This post is provided "as-is"
BAZOOKAMEGATRON
Nope - just add the classes to your application. Compile once and then you can goto the Edit columns dialog and add a progress bar column. If you are databound, then you can just change the column type of an integer column that has 0 through 100 values.< xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
-mark
DataGridView Program Manager
Microsoft
This post is provided “as-is”
Adam.Kahtava
Check out the FAQ. The DataGridView does not support embedding controls in the cells. The grid only draws the cells to look like controls. Only when a cell is in edit mode does it actually host a control.< xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
-mark
DataGridView Program Manager
Microsoft
This post is provided “as-is”
Kristian J&#246;rgensen
Muhammad Adnan
OK, I made the class and added it and all worked well.
Here is my question, why can't we just embed the progressbar control like we can the button or checkbox
Thanks
04-digit0l
Nicolas2608
Thanks.... THAT IS SWEET!
Here is my dilemma, to make this happen in all grids in my app I would I have to create a descendant DatGridView and put the code in it, correct
If this is not correct please tell me how else I could accomplish this.
ssfftt
Not sure I understand -- you just add a progress bar column and set the DataPropertyName when your DataGridView is showing content that you want. There is no support for auto changing a column's type, but you just remove and add a different DataGridView column type based upon what datasource you are showing. When the text of your label on the form identifies the datasource that should use the progress bar column you should just add it to the grid (and possibly remove any other columns). Does that make sense
-mark
DataGridView Program Manager
Microsoft
This post is provided "as-is"
R.Tutus
Mark,
This is a fantastic solution that I have spent the last couple of days searching for. Very nice work. Thank you for your contribution.
I have a question about using this in my application. For a single sourced datagrid, this works like a champ, very simple too. My application, however uses a datagrid in which the user selects multiple sources of data for. I would like to know how I can, based on the text of a label on the form, apply a datagridview progress bar to a column for only this source.
Can you explain how I might be able to do that The other selected sources for data should not have a progressbar column.
your help would be appreciated.
Chris
corbin
I know that source code is provided "as-is", but do you have any input for me on the C++/CLR version I translated If you could just point me in the right direction I would be gratefull. Thanks!
ScottTarone
I'll ask someone on the C# team if someone can convert the source. It might take a bit.
-mark
DataGridView Program Manager
Microsoft
This post is provided "as-is"
son of dad
Hello,
I got the same error because of the Paint method. At the design time, the value being pass in is null or whatever. What you can do is to make a quick check if the value is null or empty, then assign it = 1. It will solve the problem at the design time.
have fun
BAZOOKAMEGATRON
OK, thanks for the info.
I have printed FAQ but have not had time to read the whole thing.
Thanks agaion for your help.
Gep
I found this code extremely useful, except I converted it to managed C++/CLR for a project I'm working on. It compiles and runs, but I get a runtime error and am unsure of what is causing it. Here is the error I get. I tried to display the screenshot inline but apparently it won't let me, so here's the link:
DataGridView Default Error Dialog
Here is the converted code. I used the C# version as a basis for the managed C++/CLR version. Keep in mind I don't really know C#, so I may have made a "rookie mistake" in translating it to C++/CLR. Can anyone please point me in the right direction to getting this to work Thanks.