C#.Net Progress Bar Issue

Я читаю данные из файла и хочу прикрепить индикатор выполнения к этой операции. Я нашел следующий код в stackru - этот код принадлежит Уильяму Дэниелу, 20 сентября, сообщению stackru под названием "Как изменить цвет индикатора выполнения в C#.Net 3.5".

class CustomProgressBar : ProgressBar
{
    public CustomProgressBar()
    {
        this.SetStyle(ControlStyles.UserPaint, true);
    }

    protected override void OnPaintBackground(PaintEventArgs pevent)
    {
        // None... Helps control the flicker.
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        const int inset = 2;
        using (Image offscreenImage = new Bitmap(this.Width, this.Height))
        {
            using (Graphics offscreen = Graphics.FromImage(offscreenImage))
            {
                Rectangle rect = new Rectangle(0, 0, this.Width, this.Height);

                if (ProgressBarRenderer.IsSupported)
                    ProgressBarRenderer.DrawHorizontalBar(offscreen, rect);

                rect.Inflate(new Size(-inset, -inset));  // Deflate inner rectangle
                rect.Width = (int)(rect.Width * ((double)this.Value / this.Maximum));
                if (rect.Width == 0) rect.Width = 1;
                LinearGradientBrush brush = new LinearGradientBrush(rect,
                      this.BackColor, this.ForeColor, LinearGradientMode.Vertical);
                offscreen.FillRectangle(brush, inset, inset, rect.Width, rect.Height);

                e.Graphics.DrawImage(offscreenImage, 0, 0);
                offscreenImage.Dispose();
            }
        }
    }
}

Код работает нормально, за исключением следующего:

  1. Градиент, кажется, не распространяется на всю ширину полосы. Он есть, но гораздо сильнее концентрируется у основания бара и очень быстро истощается, когда мы добираемся до вершины бара. Любые предложения относительно того, как я могу это исправить?

  2. Если я помещу индикатор выполнения в форму и открою окно Internet Explorer над частью формы с индикатором выполнения, часть текста из окна Интернета будет перетекать на индикатор выполнения в форме. Понятия не имею почему и как это исправить.

Кроме того, как можно оценить продолжительность операции, которую вы хотите показать через индикатор выполнения?

Любая помощь будет принята с благодарностью. Спасибо.

3 ответа

Решение

Что касается первой части вашего вопроса - попробуйте использовать следующий конструктор для вашей кисти:

new LinearGradientBrush(new Point(0, 0), new Point(0, Height - inset * 2), BackColor, ForeColor);

Ваша текущая кисть имеет верхнюю контрольную точку на Y=inset - вот почему область от Y=0 в Y=inset все окрашено в сплошной цвет.

Попробуйте это, вам не нужно на каждой краске, чтобы создать изображение...

 class CustomProgressBar : ProgressBar
 {
  public CustomProgressBar()
  {
   this.SetStyle(ControlStyles.UserPaint|ControlStyles.OptimizedDoubleBuffer|ControlStyles.DoubleBuffer, true);
   this.UpdateStyles();
  }

  protected override void OnPaint(PaintEventArgs e)
  {
   const int inset = 2;
   Rectangle rect = this.ClientRectangle;

   var offscreen = e.Graphics;
   if (ProgressBarRenderer.IsSupported){
    ProgressBarRenderer.DrawHorizontalBar(offscreen, rect);
   }

   rect.Inflate(new Size(-inset, -inset));  // Deflate inner rectangle
   rect.Width = Convert.ToInt32(Math.Round((rect.Width * ((double)this.Value / this.Maximum))));
   if (rect.Width == 0) rect.Width = 1;
   LinearGradientBrush brush = new LinearGradientBrush(rect,this.BackColor, this.ForeColor, LinearGradientMode.Vertical);
   offscreen.FillRectangle(brush, inset, inset, rect.Width, rect.Height);
   offscreen.DrawString(Value.ToString(), this.Font,Brushes.Black,rect);
  }
 }

использование

вставка const int = 1;

на ваш другой вопрос

Вы не рисуете вообще в незаполненной части вашего индикатора выполнения. Попробуйте позвонить FillRectangle для области от rect.Right в this.Width с цветом фона. Это должно предотвратить кровотечение из перекрывающихся окон.

Другие вопросы по тегам