Visual C# を使用してスムーズな進行状況バーを作成する

この記事では、スムーズでスクロールする ProgressBar コントロールを作成するカスタム UserControl を作成する方法について説明します。

元の製品バージョン: Visual C#
元の KB 番号: 323116

概要

この記事では、シンプルでカスタムの UserControl を作成して、スムーズでスクロールする ProgressBar コントロールを作成する方法について説明します。

以前のバージョンの ProgressBar コントロール (Microsoft Windows Common Controls ActiveX コントロールで提供されているバージョンなど) では、進行状況を 2 つの異なるビューで表示できます。 これらのビューを制御するには、標準およびスムーズな設定を含む Scrolling プロパティを使用します。 スムーズスクロールは進行状況を表す単色のブロックを生成し、標準的なスクロールはセグメント化されて表示され、一連の小さなブロックまたは四角形で構成されます。

Microsoft Visual C# に含まれる ProgressBar コントロールでは、標準設定のみがサポートされています。

この記事のサンプル コードは、次のプロパティをサポートするコントロールを作成する方法を示しています。

  • Minimum: このプロパティは、進行状況の有効な値の範囲の小さい値を取得または設定します。 このプロパティの既定値は 0 (0) です。このプロパティを負の値に設定することはできません。
  • Maximum: このプロパティは、進行状況の有効な値の範囲の上限値を取得または設定します。 このプロパティの既定値は 100 です。
  • 値: このプロパティは、現在の進行状況レベルを取得または設定します。 値は、Minimum プロパティと Maximum プロパティが定義する範囲内である必要があります。
  • ProgressBarColor: このプロパティは、進行状況バーの色を取得または設定します。

カスタム ProgressBar コントロールを作成する

  1. Visual C# で新しい Windows コントロール ライブラリ プロジェクトを作成するには、次の手順に従います。

    1. Microsoft Visual Studio を起動します。

    2. [ ファイル] メニューの [ 新規] をポイントし、[ プロジェクト] をクリックします。

    3. [新しいプロジェクト] ダイアログ ボックスの [プロジェクトの種類] で [Visual C#] をクリックし、[テンプレート] の [コントロール ライブラリWindows フォームクリックします。

    4. [ 名前 ] ボックスに「 SmoothProgressBar」と入力し、[OK] をクリック します

    5. Project エクスプローラーで、既定のクラス モジュールの名前を UserControl1.cs から SmoothProgressBar.cs に変更します。

    6. UserControl オブジェクトの [プロパティ ] ウィンドウで、 Name プロパティを UserControl1 から SmoothProgressBar に変更します。

  2. この時点では、通常、そのコントロールのクラスを継承し、追加機能を追加して既存のコントロールを拡張します。 ただし、ProgressBar クラスは シール されており、継承できません。 そのため、最初からコントロールをビルドする必要があります。

    UserControl から派生したクラス内の SmoothProgressBar.cs ファイルに次のコードを追加します。

    int min = 0;// Minimum value for progress range
    int max = 100;// Maximum value for progress range
    int val = 0;// Current progress
    Color BarColor = Color.Blue;// Color of progress meter
    
    protected override void OnResize(EventArgs e)
    {
        // Invalidate the control to get a repaint.
        this.Invalidate();
    }
    
    protected override void OnPaint(PaintEventArgs e)
    {
        Graphics g = e.Graphics;
        SolidBrush brush = new SolidBrush(BarColor);
        float percent = (float)(val - min) / (float)(max - min);
        Rectangle rect = this.ClientRectangle;
    
        // Calculate area for drawing the progress.
        rect.Width = (int)((float)rect.Width * percent);
    
        // Draw the progress meter.
        g.FillRectangle(brush, rect);
    
        // Draw a three-dimensional border around the control.
        Draw3DBorder(g);
    
        // Clean up.
        brush.Dispose();
        g.Dispose();
    }
    
    public int Minimum
    {
        get
        {
            return min;
        }
    
        set
        {
            // Prevent a negative value.
            if (value < 0)
            {
                value = 0;
            }
    
            // Make sure that the minimum value is never set higher than the maximum value.
            if (value > max)
            {
                max = value;
            }
    
            min = value;
    
            // Ensure value is still in range
            if (val < min)
            {
                val = min;
            }
    
            // Invalidate the control to get a repaint.
            this.Invalidate();
        }
    }
    
    public int Maximum
    {
        get
        {
            return max;
        }
    
        set
        {
            // Make sure that the maximum value is never set lower than the minimum value.
            if (value < min)
            {
                min = value;
            }
    
            max = value;
    
            // Make sure that value is still in range.
            if (val > max)
            {
                val = max;
            }
    
            // Invalidate the control to get a repaint.
            this.Invalidate();
        }
    }
    
    public int Value
    {
        get
        {
            return val;
        }
    
        set
        {
            int oldValue = val;
    
            // Make sure that the value does not stray outside the valid range.
            if (value < min)
            {
                val = min;
            }
            else if (value > max)
            {
                val = max;
            }
            else
            {
                val = value;
            }
    
            // Invalidate only the changed area.
            float percent;
    
            Rectangle newValueRect = this.ClientRectangle;
            Rectangle oldValueRect = this.ClientRectangle;
    
            // Use a new value to calculate the rectangle for progress.
            percent = (float)(val - min) / (float)(max - min);
            newValueRect.Width = (int)((float)newValueRect.Width * percent);
    
            // Use an old value to calculate the rectangle for progress.
            percent = (float)(oldValue - min) / (float)(max - min);
            oldValueRect.Width = (int)((float)oldValueRect.Width * percent);
    
            Rectangle updateRect = new Rectangle();
    
            // Find only the part of the screen that must be updated.
            if (newValueRect.Width > oldValueRect.Width)
            {
                updateRect.X = oldValueRect.Size.Width;
                updateRect.Width = newValueRect.Width - oldValueRect.Width;
            }
            else
            {
                updateRect.X = newValueRect.Size.Width;
                updateRect.Width = oldValueRect.Width - newValueRect.Width;
            }
    
            updateRect.Height = this.Height;
    
            // Invalidate the intersection region only.
            this.Invalidate(updateRect);
        }
    }
    
    public Color ProgressBarColor
    {
        get
        {
            return BarColor;
        }
    
        set
        {
            BarColor = value;
    
            // Invalidate the control to get a repaint.
            this.Invalidate();
        }
    }
    
    private void Draw3DBorder(Graphics g)
    {
        int PenWidth = (int)Pens.White.Width;
    
        g.DrawLine(Pens.DarkGray,
        new Point(this.ClientRectangle.Left, this.ClientRectangle.Top),
        new Point(this.ClientRectangle.Width - PenWidth, this.ClientRectangle.Top));
        g.DrawLine(Pens.DarkGray,
        new Point(this.ClientRectangle.Left, this.ClientRectangle.Top),
        new Point(this.ClientRectangle.Left, this.ClientRectangle.Height - PenWidth));
        g.DrawLine(Pens.White,
        new Point(this.ClientRectangle.Left, this.ClientRectangle.Height - PenWidth),
        new Point(this.ClientRectangle.Width - PenWidth, this.ClientRectangle.Height - PenWidth));
        g.DrawLine(Pens.White,
        new Point(this.ClientRectangle.Width - PenWidth, this.ClientRectangle.Top),
        new Point(this.ClientRectangle.Width - PenWidth, this.ClientRectangle.Height - PenWidth));
    }
    
  3. [ ビルド ] メニューの [ ソリューションのビルド ] をクリックして、プロジェクトをコンパイルします。

サンプル クライアント アプリケーションを作成する

  1. [ ファイル] メニューの [ 新規] をポイントし、[ プロジェクト] をクリックします。

  2. [新しいプロジェクトの追加] ダイアログ ボックスで、[プロジェクトの種類] の [Visual C#] をクリックし、[テンプレート] の下の [アプリケーションWindows フォーム] をクリックし、[OK] をクリックします

  3. SmoothProgressBar コントロールの 2 つのインスタンスをフォームに追加するには、次の手順に従います。

    1. [ ツール ] メニューの [ ツールボックス項目の選択] をクリックします。

    2. [.NET Framework コンポーネント] タブをクリックします。

    3. [ 参照] をクリックし、[ カスタム ProgressBar コントロールの作成 ] セクションで作成したSmoothProgressBar.dllファイルを探します。

    4. [OK] をクリックします。

      注:

      SmoothProgressBar コントロールがツールボックスに追加されます。

    5. SmoothProgressBar コントロールの 2 つのインスタンスをツールボックスから Windows アプリケーション プロジェクトの既定の形式にドラッグします。

  4. ツールボックスからフォームに Timer コントロールをドラッグします。

  5. Timer コントロールのイベントに Tick 次のコードを追加します。

    if (this.smoothProgressBar1.Value > 0)
    {
        this.smoothProgressBar1.Value--;
        this.smoothProgressBar2.Value++;
    }
    else
    {
        this.timer1.Enabled = false;
    }
    
  6. ツールボックスからフォームに Button コントロールをドラッグします。

  7. Button コントロールのイベントに Click 次のコードを追加します。

    this.smoothProgressBar1.Value = 100;
    this.smoothProgressBar2.Value = 0;
    
    this.timer1.Interval = 1;
    this.timer1.Enabled = true;
    
  8. [ デバッグ ] メニューの [ スタート ] をクリックして、サンプル プロジェクトを実行します。

  9. ボタンをクリックします。

    注:

    2 つの進行状況インジケーターには、テキストの 進行状況が表示されます。 1 つの進行状況インジケーターには進行状況が増加し、もう 1 つの進行状況インジケーターには進行状況が減少またはカウントダウンの方法で表示されます。