I'm working on a Windows application in which I need to display a list of software that our company has sold, along with their current versions and the newest versions available. Users should be able to trigger commands to update each software to its latest version. 

For this purpose, we need to display a progress bar column for each software. Essentially, it's a multi-threaded Windows application where each thread appears as a row in my DataGridView. I want a progress bar in each row to indicate the updating progress of the corresponding software.

I want each row in the DataGridView to showcase a ProgressBar, indicating the progress of the corresponding software update.

 To achieve this task, I have added the class ProgressBarColumn.cs. Please see the code below:


namespace WinProgressBar
{
    // Custom DataGridView column for displaying progress bars
    public class ProgressBarColumn : DataGridViewImageColumn
    {
        public ProgressBarColumn()
        {
            // Set the cell template to a custom progress bar cell
            CellTemplate = new ProgressBarCell();
        }
    }

    // Custom DataGridView cell for displaying progress bars
    class ProgressBarCell : DataGridViewImageCell
    {
        // Static image representing an empty image
        static Image EmptyImage;

        // Static constructor to initialize the empty image
        static ProgressBarCell()
        {
            EmptyImage = new Bitmap(1, 1, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
        }

        public ProgressBarCell()
        {
            // Set the value type of the cell to integer
            ValueType = typeof(int);
        }

        // Override to provide formatted value for the cell
        protected override object GetFormattedValue(object value,
                            int rowIndex, ref DataGridViewCellStyle cellStyle,
                            TypeConverter valueTypeConverter,
                            TypeConverter formattedValueTypeConverter,
                            DataGridViewDataErrorContexts context)
        {
            // Always return the empty image
            return EmptyImage;
        }

        // Override to paint the cell content
        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)
        {
            try
            {
                if (value != null)
                {
                    // Convert the value to integer representing progress value
                    int progressValue = (int)value;
                    // Calculate the percentage of progress
                    float progressPercentage = ((float)progressValue / 100.0f);
                    
                    // Create brushes for background and foreground
                    Brush backColorBrush = new SolidBrush(cellStyle.BackColor);
                    Brush foreColorBrush = new SolidBrush(cellStyle.ForeColor);

                    // Paint the base cell content
                    base.Paint(g, clipBounds, cellBounds,
                     rowIndex, cellState, value, formattedValue, errorText,
                     cellStyle, advancedBorderStyle, (paintParts & ~DataGridViewPaintParts.ContentForeground));

                    // Check if progress is greater than 0
                    if (progressPercentage > 0.0)
                    {
                        // Draw the filled progress bar
                        g.FillRectangle(new SolidBrush(Color.FromArgb(203, 235, 108)), cellBounds.X + 2, cellBounds.Y + 2, Convert.ToInt32((progressPercentage * cellBounds.Width - 4)), cellBounds.Height - 4);
                        // Draw the progress value as text
                        g.DrawString(progressValue.ToString() + "%", cellStyle.Font, foreColorBrush, cellBounds.X + (cellBounds.Width / 2) - 5, cellBounds.Y + 2);
                    }
                    else
                    {
                        // Draw the progress value as text
                        if (DataGridView.CurrentRow.Index == rowIndex)
                            g.DrawString(progressValue.ToString() + "%", cellStyle.Font, new SolidBrush(cellStyle.SelectionForeColor), cellBounds.X + 6, cellBounds.Y + 2);
                        else
                            g.DrawString(progressValue.ToString() + "%", cellStyle.Font, foreColorBrush, cellBounds.X + 6, cellBounds.Y + 2);
                    }
                }
            }
            catch (Exception e)
            {
              
            }
        }
    }

}
The above code consists of two classes: ProgressBarColumn and ProgressBarCell. These two classes are designed to show the display of progress bars within a DataGridView, specifically for indicating the progress of software updates in a Windows application.

ProgressBarColumn:

ProgressBarColumn.cs extends the DataGridViewImageColumn class, indicating that it's a custom column for displaying images within a DataGridView.The constructor of ProgressBarColumn sets the cell template to a custom progress bar cell (ProgressBarCell).

ProgressBarCell: ProgressBarCell.cs class extends the DataGridViewImageCell class, serving as a custom cell for displaying progress bars within a DataGridView.
It contains a static image (EmptyImage) representing an empty image, which is initialized in the static constructor.The constructor sets the value type of the cell to integer.

The GetFormattedValue method is overridden to always return the empty image, ensuring that the cell initially appears empty.

Paint() method is overridden to customize the appearance of the cell. It calculates the progress percentage based on the provided value, draws a filled progress bar if the progress is greater than 0, and displays the progress value as text. 
Overall, above code provide the necessary functionality to integrate progress bars into a DataGridView, enabling the visual representation of software update progress in a Windows application.
Let's add a DataGridView to our form and utilize the progress cell.
public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        public void BindDataFirmwareGrid()
        {
            try
            {

                ProgressBarColumn progressBarColumn = new ProgressBarColumn();
                softwareupdatedataGrid.ColumnCount = 3;

                softwareupdatedataGrid.Columns[0].Name = "Software";
                softwareupdatedataGrid.Columns[0].HeaderText = "Software Name";
                softwareupdatedataGrid.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;

                softwareupdatedataGrid.Columns[1].Name = "SwVersion";
                softwareupdatedataGrid.Columns[1].HeaderText = "Sw Version";
                softwareupdatedataGrid.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;

                softwareupdatedataGrid.Columns[2].Name = "NewestVersion";
                softwareupdatedataGrid.Columns[2].HeaderText = "Newest Version";
                softwareupdatedataGrid.Columns[2].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;



                softwareupdatedataGrid.Columns.Add(progressBarColumn);
                softwareupdatedataGrid.Columns[3].Name = "Progress";
                softwareupdatedataGrid.Columns[3].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
                progressBarColumn.HeaderText = "Progress";

                object[] softwareRow1 = new object[]
                        {
                            "Security App",
                            "1.2",
                            "1.3",
                            80
                        };
                object[] softwareRow2 = new object[]
                       {
                            "Spam Remover",
                            "5.0",
                            "5.0.1",
                            40
                       };
                object[] softwareRow3 = new object[]
                       {
                            "Chat App",
                            "4.0.0",
                            "4.0.1",
                            30
                       };
                softwareupdatedataGrid.Rows.Add(softwareRow1);
                softwareupdatedataGrid.Rows.Add(softwareRow2);
                softwareupdatedataGrid.Rows.Add(softwareRow3);
            }
            catch (Exception ex)
            {

            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            BindDataFirmwareGrid();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            for (int i = 0; i < softwareupdatedataGrid.Rows.Count; i++)
            {
                if(softwareupdatedataGrid.Rows[i].Cells["Progress"].Value!=null)
                {
                    int currentState = (int)softwareupdatedataGrid.Rows[i].Cells["Progress"].Value;
                    if (currentState < 100)
                    {
                        softwareupdatedataGrid.Rows[i].Cells["Progress"].Value = currentState + 1; ;
                    }
                }
            }
        }
    }


Here is the GitHub link to download the source code: https://github.com/alokpatel2578/Show-ProgressBar-Column-In-DataGridView-With-Text-and-ProgressBars
  • The BindDataFirmwareGrid() function is responsible for setting up the DataGridView named softwareupdatedataGrid with columns and data related to software information. 
  • Creating ProgressBarColumn: Here a new instance of ProgressBarColumn is created to add a progress bar column to the DataGridView.
  • Setting Column Count: The ColumnCount property of the softwareupdatedataGrid is set to 3, indicating that there will be three columns for displaying software information.
  • Setting up Software Information Columns:Three columns are added to the DataGridView for displaying software-related information.Column 0 is for "Software Name", Column 1 is for "Software Version", and Column 2 is for "Newest Version".
  • Adding ProgressBarColumn: The ProgressBarColumn instance created earlier is added as the fourth column to the DataGridView.
  • Setting ProgressBar Column Header Text: The header text of the progress bar column is set to "Progress" to indicate its purpose.
  • Populating Data: Data for three software applications are defined using object arrays (softwareRow1, softwareRow2, softwareRow3).Each array contains information such as the software name, current version, newest version, and initial progress value.These data rows are added to the DataGridView using the Rows.Add() method.
We also added timer control in our form for showing you demo,the method loops through each row of the softwareupdatedataGrid DataGridView using a for loop. For each row, it checks if the value of the "Progress" cell is not null. If the "Progress" cell value is not null, it extracts the current progress value as an integer (currentState) from the cell. It then checks if the current progress is less than 100, indicating that the software update is not yet completed. If the progress is less than 100, it increments the current progress value by 1 and updates the "Progress" cell value with the new value.
Simulating Software Update Progress:
Overall, above code sets up the DataGridView with appropriate columns for displaying software information and a progress bar column for indicating the progress of software updates. It also populates the DataGridView with initial software data for demonstration purposes.