Следующая процедура в точности соответствует предложению MSDN. Индикатор выполнения имеет функцию OnPaint, поэтому, согласно MSDN, ваш OnPaint должен вызываться.
Причина, по которой он не вызывается, заключается в том, что вы должны заявить, что сами возьмете на себя управление. В старом MFC это называлось OwnerDrawn. Чтобы сообщить системе, что вы хотите нарисовать свой элемент управления самостоятельно, вы должны изменить стиль элемента управления. Это делается с помощью Control.SetStyle:
public partial class ColorProgressBar : System.Windows.Forms.ProgressBar
{
public ColorProgressBar()
{
InitializeComponent();
this.SetStyle(ControlStyles.UserPaint, true);
// etc, other initializations
}
Это позаботится о том, чтобы ваш OnPaint был вызван.
В качестве примера полный ColorProgressBar. Код этого класса можно найти в другом месте, но здесь он переписан как производный класс от System.Windows.Forms.ProgressBar. Это делает код намного меньше. Кроме того, у вас есть все функции Progressbar.
Этот индикатор выполнения имеет не простой цвет для полосы, а цвет градиента между двумя цветами. Его можно добавить с помощью панели инструментов, как и любой другой элемент управления. Свойства можно изменить, как если бы вы изменили свойства индикатора выполнения. Внизу окна свойств вы увидите дополнительные свойства.
Для его создания:
- Создайте свой проект
- В Solution Exploser - Add - пользовательский элемент управления дайте ему имя, например ColorProgressBar.
- Откройте код ColorProgressBar в редакторе
- Измените базовый класс с UserControl на System.Windows.Forms.ProgressBar
- Измените класс в соответствии с вашими потребностями, см. Пример ниже
Самая важная функция - это OnPaint, которая изменяет внешний вид ProgressBar. Остальное довольно просто:
- Добавьте два свойства для описания цветов градиента
В конструкторе SetStyle, как описано выше, чтобы убедиться, что ваш OnPaint вызывается:
общедоступный частичный класс ColorProgressBar: System.Windows.Forms.ProgressBar {общедоступный Color BarColorOutside {получить; установленный; } общедоступный Color BarColorCenter {получить; установленный; }
public ColorProgressBar()
{
BarColorOutside = Color.Black;
BarColorCenter = Color.Yellow;
InitializeComponent();
this.SetStyle(ControlStyles.UserPaint, true);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
// your own painting will be added later
}
Теперь проверим, работает ли эта база:
- Строить
- Создайте форму. Добавьте индикатор выполнения в форму
- Используйте свойства, чтобы присвоить индикатору выполнения значение и начальные цвета.
- Отладка, чтобы проверить, вызывается ли ваш onPaint.
Теперь файл onPaint. Залившаяся часть индикатора выполнения будет залита градиентным цветом. Для этого нам нужно знать ширину заливки и высоту индикатора выполнения. Мы можем сделать два прямоугольника: один заполнит верхнюю половину, а другой - нижнюю. Заливка будет выполняться градиентной кистью: верхняя половина от barColorOutside до barColorCenter, нижняя половина от barColorCenter до barColorOutside. Таким образом, центральный цвет будет в центре полосы прогресса.
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
// the part that has to be filled with a colored progress:
int fillWidth = (Width * Value) / (Maximum - Minimum);
if (fillWidth == 0)
{ // nothing to fill
return;
}
// the two rectangles:
Rectangle topRect = new Rectangle(0, 0, fillWidth, Height / 2);
Rectangle bottomRect = new Rectangle(0, Height / 2, fillWidth, Height);
// Paint upper half: the gradient fills the complete topRect,
// from background color to foreground color
LinearGradientBrush brush = new LinearGradientBrush(topRect, BarColorOutside,
BarColorCenter, LinearGradientMode.Vertical);
e.Graphics.FillRectangle(brush, topRect);
brush.Dispose();
// paint lower half: gradient fills the complete bottomRect,
// from foreground color to background color
brush = new LinearGradientBrush(bottomRect, BarColorCenter, BarColorOutside,
LinearGradientMode.Vertical);
e.Graphics.FillRectangle(brush, bottomRect);
brush.Dispose();
// we have missed one line in the center: draw a line:
Pen pen = new Pen(BarColorCenter);
e.Graphics.DrawLine(pen, new Point(0, topRect.Bottom),
new Point(fillWidth, topRect.Bottom));
pen.Dispose();
// if style is blocks, draw vertical lines to simulate blocks
if (Style == ProgressBarStyle.Blocks)
{
int seperatorWidth = (int)(this.Height * 0.67);
int NrOfSeparators = (int)(fillWidth / seperatorWidth);
Color sepColor = ControlPaint.LightLight(BarColorCenter);
for (int i = 1; i <= NrOfSeparators; i++)
{
e.Graphics.DrawLine(new Pen(sepColor, 1),
seperatorWidth * i, 0, seperatorWidth * i, this.Height);
}
}
}
person
Harald Coppoolse
schedule
18.06.2013