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();
}
}
}
}
Код работает нормально, за исключением следующего:
Градиент, кажется, не распространяется на всю ширину полосы. Он есть, но гораздо сильнее концентрируется у основания бара и очень быстро истощается, когда мы добираемся до вершины бара. Любые предложения относительно того, как я могу это исправить?
Если я помещу индикатор выполнения в форму и открою окно 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
с цветом фона. Это должно предотвратить кровотечение из перекрывающихся окон.