【问题标题】:c#.Net Progress Bar Issuec#.Net 进度条问题
【发布时间】:2011-11-20 03:49:44
【问题描述】:

我正在从文件中读取数据,并希望在此操作中附加一个进度条。我在 stackoverflow 上找到了以下代码 - 此代码归功于 William Daniel,9 月 20 日,stackoverflow 帖子标题为“如何在 C#.Net 3.5 中更改进度条的颜色”

class CustomProgressBar : ProgressBar
{
    public CustomProgressBar()
    {
        this.SetStyle(ControlStyles.UserPaint, true);
    }

    protected override void OnPaintBackground(PaintEventArgs pevent)
    {
        // None... Helps control the flicker.
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        const int inset = 2;
        using (Image offscreenImage = new Bitmap(this.Width, this.Height))
        {
            using (Graphics offscreen = Graphics.FromImage(offscreenImage))
            {
                Rectangle rect = new Rectangle(0, 0, this.Width, this.Height);

                if (ProgressBarRenderer.IsSupported)
                    ProgressBarRenderer.DrawHorizontalBar(offscreen, rect);

                rect.Inflate(new Size(-inset, -inset));  // Deflate inner rectangle
                rect.Width = (int)(rect.Width * ((double)this.Value / this.Maximum));
                if (rect.Width == 0) rect.Width = 1;
                LinearGradientBrush brush = new LinearGradientBrush(rect,
                      this.BackColor, this.ForeColor, LinearGradientMode.Vertical);
                offscreen.FillRectangle(brush, inset, inset, rect.Width, rect.Height);

                e.Graphics.DrawImage(offscreenImage, 0, 0);
                offscreenImage.Dispose();
            }
        }
    }
}

代码运行良好,但以下情况除外:

  1. 渐变似乎没有延伸到条的整个宽度。它在那里,但更集中在酒吧的底部附近,当我们到达酒吧的顶部时,它会很快变薄。关于如何解决此问题的任何建议?

  2. 如果我将进度条放在表单上并在表单中带有进度条的部分上方打开 Internet Explorer 窗口,则 Internet 窗口中的一些文本会渗入表单中的进度条.我不知道为什么,以及如何解决这个问题。

顺便说一句,如何估计您希望通过进度条显示的操作的长度?

任何帮助将不胜感激。谢谢。

【问题讨论】:

  • 为什么不使用 Winforms 的内置进度条?
  • 我想要一个平滑的渐变类型条,但不知道内置的条可以给我。
  • 您无法真正估计操作的长度。你可以大胆猜测,然后交叉手指,希望没有人注意到你指示的进度与操作无关。不过,处理文件时,您可能会根据处理方式获得真正的指标。
  • 我使用:int fileLines = System.IO.File.ReadAllLines(fd.FileName).Length;获取文件的大小,当我用流阅读器阅读它时更新栏。这没关系,但我想其他进程有一个通用的方法。
  • 嗨@Zeos6,看看我的回答,对你有帮助:-)

标签: c# winforms user-controls


【解决方案1】:

至于你问题的第一部分 - 尝试为你的画笔使用以下构造函数:

new LinearGradientBrush(new Point(0, 0), new Point(0, Height - inset * 2), BackColor, ForeColor);

您当前画笔的顶部控制点位于 Y=inset - 这就是为什么从 Y=0Y=inset 的区域都以纯色绘制。

【讨论】:

  • 谢谢。我尝试了这个建议,但无法让渐变出现。我将不得不再玩一些。
【解决方案2】:

您根本没有在进度条的未填充部分进行绘图。尝试使用背景颜色调用FillRectangle 以获取从rect.Rightthis.Width 的区域。它应该防止 bleeding 重叠窗口。

【讨论】:

  • 我认为以下两行代码可以做到这一点:LinearGradientBrush Brush = new LinearGradientBrush(rect, this.BackColor, this.ForeColor, LinearGradientMode.Vertical); offscreen.FillRectangle(brush, inset, inset, rect.Width, rect.Height);
  • rect.Width 小于 Width - 您根据 this.Value 设置它。其余的this.Width - rect.Width 保持原样。此外,整个 3px 插图没有绘制,也会产生出血效果。最简单的解决方案是用背景色填充 whole offscreenImage
  • 我加了一行:offscreen.Clear(Color.DarkBlue);在第二个 using 块中,这似乎有效。这就是你的想法吗?
  • 非常感谢,它有效。以及关于扩展渐变的任何想法?
  • LinearGradientBrush 中的控制点在逻辑坐标中,而不是本地(正确)坐标 - 我为此发布了另一个答案。
【解决方案3】:

试试这个,你不需要在每幅画上都创建一个图像...

 class CustomProgressBar : ProgressBar
 {
  public CustomProgressBar()
  {
   this.SetStyle(ControlStyles.UserPaint|ControlStyles.OptimizedDoubleBuffer|ControlStyles.DoubleBuffer, true);
   this.UpdateStyles();
  }

  protected override void OnPaint(PaintEventArgs e)
  {
   const int inset = 2;
   Rectangle rect = this.ClientRectangle;

   var offscreen = e.Graphics;
   if (ProgressBarRenderer.IsSupported){
    ProgressBarRenderer.DrawHorizontalBar(offscreen, rect);
   }

   rect.Inflate(new Size(-inset, -inset));  // Deflate inner rectangle
   rect.Width = Convert.ToInt32(Math.Round((rect.Width * ((double)this.Value / this.Maximum))));
   if (rect.Width == 0) rect.Width = 1;
   LinearGradientBrush brush = new LinearGradientBrush(rect,this.BackColor, this.ForeColor, LinearGradientMode.Vertical);
   offscreen.FillRectangle(brush, inset, inset, rect.Width, rect.Height);
   offscreen.DrawString(Value.ToString(), this.Font,Brushes.Black,rect);
  }
 }

使用

const int inset = 1;

关于你的其他问题

【讨论】:

  • 似乎不如上述建议有效。我已经拍摄了屏幕照片,但不知道如何在此处发布它们
  • 除了可以按照上述建议修复的渗漏问题外,似乎仍然没有 MagnatLU 的建议那么有效
  • 插入在进度条底部不起作用...渐变触及进度条矩形的底部。
  • 我觉得如果渐变色笔刷碰到底部会更好看。这或多或少是一个品味问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-22
相关资源
最近更新 更多