текст на индикаторе выполнения выходит из области видимости - PullRequest
0 голосов
/ 10 марта 2012

У меня возникают некоторые проблемы с текстом, который я пишу на индикаторе выполнения, он отображается, но затем исчезнет, ​​как только поток графического интерфейса завершит рисование, и отдельный поток, запускающий цикл, начнется снова.Я предполагаю, что это потому, что это выходит за рамки, но я не уверен, как это исправить.

общая схема выглядит следующим образом:

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
            }
        }
     }
 }

Спасибо за вашу помощь.

1 Ответ

1 голос
/ 10 марта 2012

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...