Процентная метка, вероятно, стирается, когда на индикаторе выполнения происходит следующее событие 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
), я назвал его отдельно, чтобы подчеркнуть, как запускается процесс рисования.