进度条上的文本超出范围

本文关键字:范围 文本 | 更新日期: 2023-09-27 18:27:31

im在进度条上写一些文本时遇到一些问题,它会显示,但一旦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
            }
        }
     }
 }

谢谢你的帮助。

进度条上的文本超出范围

当进度条上发生下一个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属性设置器内部),我单独调用它只是为了强调绘画过程是如何触发的。