我创建了一个扩展ProgressBar
的类 - 主要是为了允许更多的自定义,所以我可以在条上绘制刻度,选择我想要的颜色,并删除默认情况下获得的动画,它在大多数情况下工作正常,但是第一次更改值时,在实际更新之前总会有大约一秒的延迟。所有后续更改都会立即发生,只是第一次从0变为1才会延迟。我试图确定是否存在某种内置延迟,我必须以某种方式规避?这是我的代码的相关部分:
public class FancyProgressBar : ProgressBar
{
//... various properties and fields
public FancyProgressBar()
{
this.SetStyle(ControlStyles.UserPaint, true);
this.DoubleBuffered = true;
InitializeComponent();
}
public FancyProgressBar(IContainer container)
{
this.SetStyle(ControlStyles.UserPaint, true);
this.DoubleBuffered = true;
container.Add(this);
InitializeComponent();
}
protected override void OnPaint(PaintEventArgs e)
{
Rectangle rec = e.ClipRectangle;
rec.Width = (int)(rec.Width * ((double)Value / Maximum)) - 4;
if (ProgressBarRenderer.IsSupported)
ProgressBarRenderer.DrawHorizontalBar(e.Graphics, e.ClipRectangle);
else
e.Graphics.DrawRectangle(Pens.Gray, 0, 0, this.Width, this.Height);
rec.Height = rec.Height - 4;
DrawBar(e.Graphics, new Color[] { Color1, Color2, Color3 }, e.ClipRectangle, rec);
if (Ticks > 0)
{
int lineHeight = this.Height * TickHeight / 100;
float spacing = this.Width / Ticks;
for (int i = 1; i < Ticks; i++)
{
Pen pen = new Pen(new SolidBrush(TickColor));
e.Graphics.DrawLine(pen, new Point((int)(spacing * i)-2, Height), new Point((int)(spacing * i)-2, Height - lineHeight));
}
}
}
//This is broken out into a separate function because I have another version
//that draws more than one bar. Shouldn't make a difference though.
private void DrawBar(Graphics g, Color[] colors, Rectangle clipRec, Rectangle drawRec)
{
using (System.Drawing.Drawing2D.LinearGradientBrush l =
new System.Drawing.Drawing2D.LinearGradientBrush(clipRec, Color.Green, Color.Red, 0f))
{
System.Drawing.Drawing2D.ColorBlend lb = new System.Drawing.Drawing2D.ColorBlend();
lb.Colors = colors;
lb.Positions = new float[] { 0, PositionColor2, 1.0f };
l.InterpolationColors = lb;
g.FillRectangle(l, 2, 2, drawRec.Width, drawRec.Height);
}
using (System.Drawing.Drawing2D.LinearGradientBrush l2 =
new System.Drawing.Drawing2D.LinearGradientBrush(clipRec,
Color.FromArgb(147, 255, 255, 255),
Color.FromArgb(0, 255, 255, 255),
System.Drawing.Drawing2D.LinearGradientMode.Vertical))
{
System.Drawing.Drawing2D.ColorBlend lb = new System.Drawing.Drawing2D.ColorBlend();
lb.Colors = new Color[] { Color.FromArgb(40, 255, 255, 255), Color.FromArgb(147, 255, 255, 255),
Color.FromArgb(40, 255, 255, 255), Color.FromArgb(0, 255, 255, 255) };
lb.Positions = new float[] { 0, 0.12f, 0.39f, 1.0f };
l2.InterpolationColors = lb;
l2.WrapMode = System.Drawing.Drawing2D.WrapMode.Tile;
g.FillRectangle(l2, 2, 2, drawRec.Width, drawRec.Height);
}
}
编辑: 我应该声明我没有使用ProgressBar作为实际的进度条。在加载东西的时候它没有运行,只是在UI中显示一些值,所以没有其他一些昂贵的计算同时发生。
答案 0 :(得分:0)
使用BackgroundWorker尝试使用ProgressBar,因为UI元素与Thread有区别。像这样:
BackgroundWorker bwEx = new BackgroundWorker();
bwEx.DoWork += bwEx_DoWork;
bwEx.RunWorkerCompleted += bwEx_RunWorkerCompleted;
bwEx.ProgressChanged += bwEx_ProgressChanged;
bwEx.WorkerReportsProgress = true;
bwEx.RunWorkerAsync();
private void bwEx_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
yourProgress.Value = e.ProgressPercentage;
}
private void bwEx_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
}
private void bwEx_DoWork(object sender, DoWorkEventArgs e)
{
}
答案 1 :(得分:0)
好的,我终于想出了一个真正的解决方案。 ProgressBar的东西完全没必要。我刚刚将FancyProgressBar
更改为Control
而不是ProgressBar
,然后为Value
,Minimum
,Maximum
和{{添加了字段1}},这是我仍然使用的Step
的唯一部分,因为我已经覆盖了绘图部分。只有我必须添加的其他内容是每当值发生变化时在进度条上调用ProgressBar
。从Invalidate()
扩展时这不起作用,ProgressBar
似乎有某种内置延迟,可能是因为它被设计为多线程对象。由于我实际上并没有将它用作加载条,因此完全没必要使用多线程。