0

System.Windows.Forms.ProgressBar から派生したクラスを作成しました。MSDN が推奨する方法に従いました。

  • プロジェクトにユーザー コントロールを追加する
  • ユーザー コントロールのコードを開く
  • System.Windows.Forms.UserControl から派生する代わりに、ProgressBar から派生します。

さらに、OnPaint をオーバーライドするので、自分でペイントできます。

protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);
    // etc, do your own painting.

しかし、この関数は決して呼び出されません。ブレークポイントはここでブレークしません。プログレスバーは正常に描画されます。私は何が欠けていますか?

4

1 に答える 1

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 からの派生クラスとして書き直されています。これにより、コードが大幅に小さくなります。さらに、プログレスバーのすべての機能があります。

このプログレスバーには、バーの単色ではなく、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);
        }
    }
}
于 2013-06-18T07:19:48.610 に答える