次の手順は、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 からの派生クラスとして書き直されています。これにより、コードが大幅に小さくなります。さらに、プログレスバーのすべての機能があります。
このプログレスバーには、バーの単色ではなく、2 つの色の間のグラデーション カラーがあります。他のコントロールと同様に、ツールボックスを使用して追加できます。プログレスバーのプロパティを変更するように、プロパティを変更できます。プロパティ ウィンドウの下部に、追加のプロパティが表示されます。
作成するには:
- プロジェクトを作成する
- Solution Exploser - Add - user control で、ColorProgressBar などの名前を付けます。
- エディターで ColorProgressBar のコードを開きます
- 基本クラスを UserControl から System.Windows.Forms.ProgressBar に変更します。
- 必要に応じてクラスを変更します。以下の例を参照してください
最も重要な関数は、ProgressBar の外観を変更する OnPaint です。残りは非常に簡単です。
- グラデーション カラーを記述する 2 つのプロパティを追加します。
OnPaint が確実に呼び出されるように、上記のように SetStyle のコンストラクターで次のようにします。
パブリック部分クラス 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 が呼び出されているかどうかを確認します。
今オンペイント。プログレスバーの塗りつぶされた部分はグラデーションカラーで塗りつぶされます。そのためには、プログレス バーの塗り幅と高さを知る必要があります。2 つの長方形を作成できます。1 つは上半分を塗りつぶし、もう 1 つは下半分を塗りつぶします。塗りつぶしはグラデーション ブラシで行われます。上半分は 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);
}
}
}