it鸟 2024-05-11 10:48 采纳率: 80%
浏览 14
已结题

C# datagridview 单元格显示进度及值

C# datagridview 单元格显示进度,数字有重复。

img

我贴一下代码:
1.绑定datasource

  private void InitializeDataGridView()
        {
            // 创建 DataTable 用于存储数据
            #region
            dataTable = new DataTable();
            dataTable.Columns.Add("Item", typeof(string));
            dataTable.Columns.Add("WO", typeof(string));
            dataTable.Columns.Add("PN", typeof(string));
            dataTable.Columns.Add("WO Qty", typeof(int));
            dataTable.Columns.Add("Testing", typeof(string));
            dataTable.Columns.Add("Inspection", typeof(string));
            dataTable.Columns.Add("FQC", typeof(string));
            dataTable.Columns.Add("Packaging", typeof(string));

            // 添加数据行
            AddDataRow("931300123456", "117G0-037781-R1", 150, 150, 140, 140, 120);
            AddDataRow("931303123456", "117G0-037784-R1", 30, 30, 25, 20, 0);
            AddDataRow("931304123456", "117G0-037785-R1", 100, 80, 70, 70, 20);
            AddDataRow("931306123456", "117G0-037787-R1", 0, 0, 0, 0, 0);
            AddDataRow("931307123456", "117G0-037788-R1", 60, 60, 50, 50, 20);
            #endregion
            // 设置 DataGridView 的数据源            
            //dataGridView2.DataSource = dataTable;
            #region
            dataGridView2.Columns.Add("Col1","项次1");
            dataGridView2.Columns.Add("Col2", "项次2");
            dataGridView2.Columns.Add("Col3", "项次3");
            dataGridView2.Columns.Add("Col4", "项次4");
            dataGridView2.Columns.Add("Col5", "项次5");
            dataGridView2.Columns.Add("Col6", "项次6");
            dataGridView2.Columns.Add("Col7", "项次7");
            dataGridView2.Columns.Add(new ProgressColumn()); // 添加进度列
            dataGridView2.Columns.Add(new ProgressColumn());
            dataGridView2.Rows.Add("931300123001", "117G0-037781-R1", "150", "150/150", "150/140","150/50","150/0","150/30","150/150");
            dataGridView2.Rows.Add("931300123002", "117G0-037781-R1", "100", "100/100", "100/80", "100/50", "100/0","100/60", "60/60");
            #endregion
            // 设置样式
            dataGridView2.CellPainting += DataGridView1_CellPainting;
        }

2.添加row

private void AddDataRow(string wo, string pn, int woQty, int testing, int inspection, int fqc, int packaging)
        {
            dataTable.Rows.Add(new object[]
            {
                "项次",
                wo,
                pn,
                woQty,
                $"{woQty}/{testing}",
                $"{woQty}/{inspection}",
                $"{woQty}/{fqc}",
                $"{woQty}/{packaging}"
            });
        }

3.cell_paint

private void DataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
        {
            if (e.RowIndex >= 0 && e.ColumnIndex > 3)
            {
                string value = Convert.ToString(dataGridView2[e.ColumnIndex, e.RowIndex].Value);
                if (string.IsNullOrEmpty(value))
                    return;
                string[] parts = value.Split('/');
                int total = int.Parse(parts[0]);
                int current = int.Parse(parts[1]);
                SolidBrush drawBrush = new SolidBrush(Color.Black);
                if (current == total)
                {
                    drawBrush = new SolidBrush(Color.Green);
                }
                else if (current > 0 && current < total)
                {
                    drawBrush = new SolidBrush(Color.FromArgb(255, 255, 153)); // 黄色前景
                    dataGridView2[e.ColumnIndex, e.RowIndex].Style.SelectionBackColor = Color.Transparent; // 透明背景
                }
                else
                {
                    dataGridView2[e.ColumnIndex, e.RowIndex].Style.SelectionBackColor = Color.Transparent; // 透明背景
                }
                e.Paint(e.CellBounds, DataGridViewPaintParts.All & DataGridViewPaintParts.ContentBackground & DataGridViewPaintParts.ContentForeground);
               // e.Graphics.DrawString(value, dataGridView2.Font, drawBrush, e.CellBounds.X+2, e.CellBounds.Y+2);
                drawBrush.Dispose();
            }
        }

4.对象

 public class ProgressColumn : DataGridViewColumn
        {
            public ProgressColumn() : base(new ProgressCell())
            {
                this.CellTemplate = new ProgressCell();
            }
        }

5.单元格显示

public class ProgressCell : DataGridViewTextBoxCell
        {
            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)
            {
                base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
                if (formattedValue != null && formattedValue.ToString().Contains("/"))
                {
                    string[] parts = formattedValue.ToString().Split('/');
                    if (parts.Length == 2 && int.TryParse(parts[0], out int total) && int.TryParse(parts[1], out int completed))
                    {
                        float progress = (float)completed / total;
                        Brush brush;
                        if (progress == 1)
                            brush = new SolidBrush(Color.Green); // 全部完成,绿色
                        else if (progress > 0 && progress < 1)                        
                            brush = new SolidBrush(Color.Yellow); // 部分完成,前景黄色                                                                
                        else // progress == 0的情况                       
                           return; // 或者您可以根据需求添加特定处理                       
                        graphics.FillRectangle(brush, cellBounds.Left, cellBounds.Top, (int)(cellBounds.Width * progress), cellBounds.Height);
                        //显示单元格的值                       
                        string text = string.Format("{0}", value);
                        SizeF rf = graphics.MeasureString(text, cellStyle.Font);
                        float x = cellBounds.X + (cellBounds.Width - rf.Width) / 2f;
                        float y = cellBounds.Y + (cellBounds.Height - rf.Height) / 2f;
                        graphics.DrawString(text, cellStyle.Font, new SolidBrush(cellStyle.ForeColor), x, y);                        
                    }
                }
            }
        }

  • 写回答

13条回答 默认 最新

  • 笑面虎 2024-05-11 10:48
    关注

    以下内容由CHATGPT及笑面虎共同生成、有用望采纳:


    您提问的目的是想要在C#的DataGridView控件中显示进度条,并且每个进度条旁边显示相应的数值。但是您遇到了一些问题,比如单元格中的数字有重复,以及可能的进度条显示不正确。

    图片内容

    • 您上传的图片显示了一个DataGridView的界面,其中包含了多个列,每个单元格显示了进度条和一些数值。例如,"150/140" 表示进度条的总值为150,当前值为140。

    问题出现原因

    • 根据您提供的代码和描述,问题可能出现在以下几个方面:
      1. DataGridView1_CellPainting 方法中,您尝试自定义单元格的绘制方式,但是没有正确地绘制进度条。
      2. ProgressCell 类中的 Paint 方法可能没有正确地处理所有的绘制逻辑,尤其是在计算进度条宽度时。

    问题解决方案

    • 为了解决您的问题,我们需要确保 ProgressCell 类中的 Paint 方法能够正确地绘制进度条,并且不会产生重复的数字。以下是修改后的 ProgressCell 类的代码:
    public class ProgressCell : DataGridViewTextBoxCell
    {
        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)
        {
            base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts & ~DataGridViewPaintParts.ContentForeground); // 排除前景内容的绘制
    
            if (formattedValue != null && formattedValue.ToString().Contains("/"))
            {
                string[] parts = formattedValue.ToString().Split('/');
                if (parts.Length == 2 && int.TryParse(parts[0], out int total) && int.TryParse(parts[1], out int completed))
                {
                    float progress = (float)completed / total;
                    Brush brush;
                    if (progress == 1)
                        brush = new SolidBrush(Color.Green); // 全部完成,绿色
                    else if (progress > 0 && progress < 1)                        
                        brush = new SolidBrush(Color.Yellow); // 部分完成,前景黄色
                    else // progress == 0的情况                       
                        brush = new SolidBrush(Color.Red); // 未开始,红色
    
                    graphics.FillRectangle(brush, cellBounds.Left, cellBounds.Top, (int)(cellBounds.Width * progress), cellBounds.Height);
    
                    // 重新绘制文本,以适应新绘制的进度条背景
                    string text = string.Format("{0}/{1}", completed, total);
                    using (StringFormat stringFormat = new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center })
                    {
                        graphics.DrawString(text, cellStyle.Font, new SolidBrush(cellStyle.ForeColor), cellBounds, stringFormat);
                    }
                }
            }
        }
    }
    

    代码运行方式

    • 您需要将上述代码替换到您的项目中相应的位置,并确保 ProgressColumnProgressCell 类被正确地使用在您的 DataGridView 控件中。
    • 运行您的C#项目,DataGridView应该会显示进度条和旁边的数值,且没有重复。

    代码预期运行结果

    项次1 | 项次2 | 项次3 | 项次4 | 项次5 | 项次6 | 进度条1 | 进度条2
    ----------------------------------------------
    931300123001 | 117G0-037781-R1 | 150 | 150/150 | 150/140 | 150/50 | 150/0 | 150/30 | 150/150
    931300123002 | 117G0-037781-R1 | 100 | 100/100 | 100/80 | 100/50 | 100/0 | 100/60 | 60/60
    

    每一列的进度条都会根据旁边的数值显示相应的进度。

    推荐相关链接

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(12条)

报告相同问题?

问题事件

  • 系统已结题 5月19日
  • 已采纳回答 5月11日
  • 创建了问题 5月11日