如何创建类为WinForm标签设置多色文本显示下载进度
解决WinForm标签多行多色进度显示问题
你的代码核心问题是控制台颜色设置Console.ForegroundColor对WinForm的Label控件完全无效——Label的Text属性是纯文本格式,无法存储颜色信息,所有文本会统一继承Label的ForeColor属性,因此才会出现全红的情况。下面提供两种可行的实现方案:
方案一:改用RichTextBox控件(简单易实现)
RichTextBox支持富文本格式,能轻松实现不同文本段的颜色区分,是最快的解决方案。
1. 替换控件
将窗体上的lblDownloadProgress标签替换为RichTextBox控件(可保留原命名,或改为rtbDownloadProgress),并设置以下属性:
ReadOnly = true(禁止用户编辑)BorderStyle = BorderStyle.None(模拟Label的无框样式)BackColor与原Label保持一致(例如SystemColors.Control)
2. 修改进度更新逻辑
删除原DownloadProgressFormatter类,直接在进度计算后构建富文本内容:
// 计算进度信息 int imagesLeft = totalLinks - downloadedCount; double totalMBs = Math.Round((double)totalLinks * data.Length / 1024.0 / 1024.0, 3); double downloadedMBs = Math.Round((double)downloadedCount * data.Length / 1024.0 / 1024.0, 3); double speed = Math.Round((double)data.Length / 1024.0 / 1024.0 / sw.Elapsed.TotalSeconds, 3); // 清空原有内容,设置粗体字体 rtbDownloadProgress.Clear(); rtbDownloadProgress.Font = new Font(rtbDownloadProgress.Font, FontStyle.Bold); // 定义颜色 Color propColor = Color.Green; Color valueColor = Color.Red; // 逐行添加带颜色的文本 AddColoredText(rtbDownloadProgress, " Size: ", propColor); AddColoredText(rtbDownloadProgress, $"{totalMBs} MB\n", valueColor); AddColoredText(rtbDownloadProgress, " Downloaded: ", propColor); AddColoredText(rtbDownloadProgress, $"{downloadedMBs} MB\n", valueColor); AddColoredText(rtbDownloadProgress, " Images Left: ", propColor); AddColoredText(rtbDownloadProgress, $"{imagesLeft}\n", valueColor); AddColoredText(rtbDownloadProgress, " Speed: ", propColor); AddColoredText(rtbDownloadProgress, $"{speed} MB/s", valueColor); // 辅助方法:向RichTextBox添加指定颜色的文本 private void AddColoredText(RichTextBox rtb, string text, Color color) { rtb.SelectionStart = rtb.TextLength; rtb.SelectionLength = 0; rtb.SelectionColor = color; rtb.AppendText(text); rtb.SelectionColor = rtb.ForeColor; // 恢复默认颜色 }
方案二:自定义Label控件(纯Label实现)
如果必须使用Label控件,可以自定义控件并重写OnPaint方法,手动绘制每行文本并设置颜色:
1. 创建自定义Label类
using System.Drawing; using System.Windows.Forms; public class ColoredProgressLabel : Label { // 用于存储进度数据的属性 public double TotalMBs { get; set; } public double DownloadedMBs { get; set; } public int ImagesLeft { get; set; } public double Speed { get; set; } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); e.Graphics.Clear(this.BackColor); // 清空原有绘制内容 // 定义字体和颜色 Font boldFont = new Font(this.Font, FontStyle.Bold); Color propColor = Color.Green; Color valueColor = Color.Red; float yPos = 0; // 垂直位置偏移量 // 逐行绘制文本 DrawTextLine(e.Graphics, " Size: ", propColor, $"{TotalMBs} MB", valueColor, boldFont, ref yPos); DrawTextLine(e.Graphics, " Downloaded: ", propColor, $"{DownloadedMBs} MB", valueColor, boldFont, ref yPos); DrawTextLine(e.Graphics, " Images Left: ", propColor, $"{ImagesLeft}", valueColor, boldFont, ref yPos); DrawTextLine(e.Graphics, " Speed: ", propColor, $"{Speed} MB/s", valueColor, boldFont, ref yPos); } // 辅助方法:绘制一行包含两种颜色的文本 private void DrawTextLine(Graphics g, string propText, Color propColor, string valueText, Color valueColor, Font font, ref float yPos) { // 绘制绿色的属性文本 SizeF propSize = g.MeasureString(propText, font); g.DrawString(propText, font, new SolidBrush(propColor), 0, yPos); // 绘制红色的数值文本 g.DrawString(valueText, font, new SolidBrush(valueColor), propSize.Width, yPos); // 更新垂直位置,准备绘制下一行 yPos += propSize.Height; } }
2. 使用自定义Label
- 在窗体设计器中,将原有Label替换为
ColoredProgressLabel(或在代码中直接实例化) - 在进度更新处设置属性并触发重绘:
// 计算进度信息 int imagesLeft = totalLinks - downloadedCount; double totalMBs = Math.Round((double)totalLinks * data.Length / 1024.0 / 1024.0, 3); double downloadedMBs = Math.Round((double)downloadedCount * data.Length / 1024.0 / 1024.0, 3); double speed = Math.Round((double)data.Length / 1024.0 / 1024.0 / sw.Elapsed.TotalSeconds, 3); // 设置自定义Label的进度属性 coloredProgressLabel.TotalMBs = totalMBs; coloredProgressLabel.DownloadedMBs = downloadedMBs; coloredProgressLabel.ImagesLeft = imagesLeft; coloredProgressLabel.Speed = speed; // 触发控件重绘,更新显示内容 coloredProgressLabel.Invalidate();
内容的提问来源于stack exchange,提问作者Daniel Lip
相关产品推荐
相关产品推荐

