C# DataGridView 添加进度条
目录
1 重绘类
2 添加数据
本文介绍了一个自定义DataGridView进度条单元格的实现方案。通过继承DataGridViewImageCell并重写Paint方法,实现了在单元格中绘制进度条的效果。关键点包括:1)使用progressBrush绘制进度条;2)处理进度值转换确保0-100范围;3)解决Int32到Image的强制转换错误。同时定义了DataGridViewProgressColumn列类型和TestProgressData数据结构,并提供了数据绑定示例。该方案适用于需要显示进度状态的WinForms应用,解决了默认DataGridView无法直接显示进度条的问题。
1 重绘类
public class DataGridViewProgressCell : DataGridViewImageCell{// 用于绘制进度条的刷子private static readonly Brush progressBrush = new SolidBrush(Color.LightSeaGreen);private static readonly Brush textBrush = new SolidBrush(Color.Black);private static readonly Pen borderPen = new Pen(Color.DarkGray);public DataGridViewProgressCell(){// 设置单元格的值类型为intValueType = typeof(int);}// 重写单元格的类型public override Type ValueType{get { return typeof(int); }set { base.ValueType = typeof(int); }}// 提供默认值public override object DefaultNewRowValue{get { return 0; }}// 关键修复:重写此方法避免类型转换错误protected override object GetFormattedValue(object value,int rowIndex,ref DataGridViewCellStyle cellStyle,TypeConverter valueTypeConverter,TypeConverter formattedValueTypeConverter,DataGridViewDataErrorContexts context){// 直接返回空,避免将int强制转为Imagereturn null;}// 重绘单元格,绘制进度条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, null, errorText, cellStyle, advancedBorderStyle,paintParts & ~DataGridViewPaintParts.ContentForeground);int progress = 0;// 尝试将值转换为进度值(0-100)if (value != null && int.TryParse(value.ToString(), out int val)){progress = Math.Max(0, Math.Min(100, val)); // 确保值在0-100之间}// 绘制单元格背景using (Brush backBrush = new SolidBrush(cellStyle.BackColor)){graphics.FillRectangle(backBrush, cellBounds);}// 绘制进度条背景Rectangle progressRect = new Rectangle(cellBounds.X + 2,cellBounds.Y + 2,cellBounds.Width - 4,cellBounds.Height - 4);graphics.FillRectangle(Brushes.White, progressRect);// 绘制进度条int progressWidth = (int)((progressRect.Width * progress) / 100.0);Rectangle fillRect = new Rectangle(progressRect.X,progressRect.Y,progressWidth,progressRect.Height);graphics.FillRectangle(progressBrush, fillRect);// 绘制进度条边框graphics.DrawRectangle(borderPen, progressRect);// 绘制进度文本string text = $"{progress}%";SizeF textSize = graphics.MeasureString(text, cellStyle.Font);graphics.DrawString(text, cellStyle.Font, textBrush,cellBounds.X + (cellBounds.Width - textSize.Width) / 2,cellBounds.Y + (cellBounds.Height - textSize.Height) / 2);}}// 自定义进度条列public class DataGridViewProgressColumn : DataGridViewColumn{public DataGridViewProgressColumn(){CellTemplate = new DataGridViewProgressCell();this.ValueType = typeof(int);// 关键修复:禁用默认图像生成this.DefaultCellStyle.NullValue = null;DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;}}// 定义数据结构体public class TestProgressData{public string devIDInfo { get; set; }public int progressValue { get; set; } // 进度值(0-100)public string progressStatus { get; set; } // 实时进度状态public string testResult { get; set; } // 测试结果public string errorMessage { get; set; } // 错误信息}
2 添加数据
private void InitializeDeviceInfoGrid(int group){//dataGridView_data.DataError += dataGridView_DataError;// 设置DataGridView属性//dataGridView_data.Dock = DockStyle.Fill;dataGridView_data.AllowUserToAddRows = false;dataGridView_data.ReadOnly = true;dataGridView_data.RowHeadersVisible = false;// 添加状态列dataGridView_data.Columns.Add(new DataGridViewTextBoxColumn{HeaderText = "设备名",DataPropertyName = "devIDInfo",Width = 150});// 添加进度条列DataGridViewProgressColumn progressColumn = new DataGridViewProgressColumn();progressColumn.HeaderText = "进度";progressColumn.Width = 200;progressColumn.DataPropertyName = "progressValue";dataGridView_data.Columns.Add(progressColumn);// 添加状态列dataGridView_data.Columns.Add(new DataGridViewTextBoxColumn{HeaderText = "实时进度状态",DataPropertyName = "progressStatus",Width = 150});// 添加测试结果列dataGridView_data.Columns.Add(new DataGridViewTextBoxColumn{HeaderText = "测试结果",DataPropertyName = "testResult",Width = 120});// 添加错误信息列dataGridView_data.Columns.Add(new DataGridViewTextBoxColumn{HeaderText = "错误信息",DataPropertyName = "errorMessage",Width = 200});AddTestData();// 绑定数据//dataGridView_data.DataSource = dataList;}// 添加测试数据private void AddTestData(){// 添加几行测试数据dataList.Add(new TestProgressData{devIDInfo = "123",progressValue = 30,progressStatus = "正在处理",testResult = "",errorMessage = ""}); ;dataList.Add(new TestProgressData{devIDInfo = "123",progressValue = 100,progressStatus = "处理完成",testResult = "成功",errorMessage = ""});dataList.Add(new TestProgressData{devIDInfo = "123",progressValue = 50,progressStatus = "正在验证",testResult = "",errorMessage = ""});dataList.Add(new TestProgressData{devIDInfo = "123",progressValue = 75,progressStatus = "正在传输",testResult = "",errorMessage = "网络延迟"});dataList.Add(new TestProgressData{devIDInfo = "123",progressValue = 100,progressStatus = "处理完成",testResult = "失败",errorMessage = "文件格式错误"});// 刷新数据绑定dataGridView_data.DataSource = null;dataGridView_data.DataSource = dataList;//dataGridView_data.Refresh();}
3 遇到的问题
DataGridView错误:从“System.Int32”到“System.Drawing.Image”的强制转换无效。,行:0,列:1