即时通讯在进度条上写入一些文本时遇到一些问题,它会显示但是一旦GUI线程完成绘图就会消失,并且运行循环的单独线程会再次开始。我假设这是因为它超出范围,但我不知道如何解决它。
总体布局如下:
namespace namespace1
{
public partial class Form1:Form
{
....
}
public class ProgressBar
{
public void SubscribeToUpdateEvent()
{
//subscribe incrementPB to event
}
public void IncrementPB(object sender, EventArgs e)
{
//Update progress bar's value
DrawPercentage(value);
}
public void DrawPercentage(Value)
{
using (Graphics Draw = statusBar.CreateGraphics())
{
Draw.DrawString(percentage.ToString() + "%", ProgressBar.DefaultFont, Brushes.Black, new PointF((statusBar.Width / 2) - ((Draw.MeasureString(percentage.ToString() + "%", ProgressBar.DefaultFont)).Width / 2.0F),
(statusBar.Height / 2) - ((Draw.MeasureString(percentage.ToString() + "%", ProgressBar.DefaultFont)).Height / 2.0F)));
}
}
}
//第二个文件,它在一个单独的线程上处理一堆数据,并在每次循环后引发事件。
namespace namespace2
{
public class MyClass
{
public void iterator()
{
for(int i=0;i<10;i++)
{
//raise event to update the progress bar here
}
}
}
}
感谢您的帮助。
答案 0 :(得分:1)
当进度条上发生下一个Paint
事件时,百分比标签可能会被删除。尝试将进度条实现为用户控件,这样您可以覆盖OnPaint
方法并在那里呈现文本(在base.OnPaint(e)
之后)。
我做了一些简单的课程来模拟你的情况。以下是适用于我的方法:
1)进度条控件(简单实现,只是为了概述OnPaint的基本思想):
public partial class CustomProgressBar : UserControl
{
public int Percentage { get; set; }
public CustomProgressBar()
{
InitializeComponent();
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics g = e.Graphics;
Rectangle bounds = new Rectangle(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width - 1, ClientRectangle.Height - 1);
// Paint a green bar indicating the progress.
g.FillRectangle
(
Brushes.LimeGreen,
new Rectangle
(
bounds.X,
bounds.Y,
(int)(bounds.Width * Percentage / 100.0),
bounds.Height
)
);
// Draw a black frame around the progress bar.
g.DrawRectangle(Pens.Black, bounds);
// Draw the percentage label.
TextRenderer.DrawText(g, Percentage + "%", Font, bounds, ForeColor);
}
}
2)表示在后台线程中运行的作业的类:
public class BackgroundJob
{
public event Action<object, int> StepCompleted;
public void Execute()
{
const int TotalSteps = 10;
for (int step = 1; step <= TotalSteps; step++)
{
// Execute some heavy work here.
Thread.Sleep(1000);
// Calculate percentage (0..100).
int percentage = (int)(step * 100.0 / TotalSteps);
// Notify the subscribers that the step has been completed.
OnStepCompleted(percentage);
}
}
protected virtual void OnStepCompleted(int percentage)
{
if (StepCompleted != null)
{
StepCompleted(this, percentage);
}
}
}
3)表格类。包含自定义进度条控件,并在按下按钮时启动后台作业。
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private void btnStartJob_Click(object sender, EventArgs e)
{
Thread backgroundThread = new Thread
(
() =>
{
var job = new BackgroundJob();
job.StepCompleted += job_StepCompleted;
job.Execute();
}
);
backgroundThread.Start();
}
private void job_StepCompleted(object sender, int percentage)
{
progressBar.Percentage = percentage;
// Force the progress bar to redraw itself.
progressBar.Invalidate();
}
}
你可以在内部调用Invalidate()
(在Percentage
属性设置器中),我单独调用它只是为了强调如何触发绘制过程。