我创建了一个派生自System.Windows.Forms.ProgressBar的类。我按照MSDN建议的方法:
此外,我重写了OnPaint,所以我可以自己绘画:
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
// etc, do your own painting.
然而这个功能从未被调用过。断点不会在这里破裂。进度条正常绘制。我错过了什么?
答案 0 :(得分:2)
遵循的程序正如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的所有功能。
此进度条没有条形的纯色,而是两种颜色之间的渐变色。它可以像任何其他控件一样使用工具箱添加。可以更改属性,就像更改进度条的属性一样。在属性窗口的底部,您将看到额外的属性。
创建它:
最重要的功能是OnPaint,它将改变ProgressBar的外观。其余的很简单:
在构造函数中,如上所述SetStyle以确保调用OnPaint:
public partial class ColorProgressBar:System.Windows.Forms.ProgressBar { public Color BarColorOutside {get;组; } public Color BarColorCenter {get;组; }
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。填充的Progressbar部分将填充渐变颜色。为此,我们需要知道进度条的填充宽度和高度。我们可以制作两个矩形:一个填充上半部分,另一个填充下半部分。填充将使用渐变画笔完成:从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);
}
}
}