Visual C#을 사용하여 부드러운 진행률 표시줄 만들기

이 문서에서는 사용자 지정 UserControl을 만들어 원활하고 스크롤하는 ProgressBar 컨트롤을 만드는 방법에 대한 정보를 제공합니다.

원래 제품 버전: Visual C#
원본 KB 번호: 323116

요약

이 문서에서는 간단한 사용자 지정 UserControl을 만들어 원활하고 스크롤하는 ProgressBar 컨트롤을 만드는 방법을 보여 줍니다.

Microsoft Windows Common Controls ActiveX 컨트롤과 함께 제공되는 버전과 같은 이전 버전의 ProgressBar 컨트롤에서는 두 가지 보기에서 진행률을 볼 수 있습니다. 이러한 보기를 제어하려면 표준 및 부드러운 설정이 포함된 Scrolling 속성을 사용합니다. 부드러운 스크롤은 진행률을 나타내는 단색 블록을 생성하고 표준 스크롤은 분할된 것으로 나타나며 일련의 작은 블록 또는 사각형으로 구성됩니다.

Microsoft Visual C#에 포함된 ProgressBar 컨트롤은 표준 설정만 지원합니다.

이 문서의 샘플 코드는 다음 속성을 지원하는 컨트롤을 만드는 방법을 보여 줍니다.

  • 최소: 이 속성은 진행률에 유효한 값 범위의 하한값을 가져오거나 설정합니다. 이 속성의 기본값은 0(0)입니다. 이 속성을 음수 값으로 설정할 수 없습니다.
  • 최대: 이 속성은 진행률에 유효한 값 범위의 상한값을 가져오거나 설정합니다. 이 속성의 기본값은 100입니다.
  • 값: 이 속성은 현재 진행률을 가져오거나 설정합니다. 값은 Minimum 및 Maximum 속성이 정의하는 범위에 있어야 합니다.
  • ProgressBarColor: 이 속성은 진행률 표시줄의 색을 가져오거나 설정합니다.

사용자 지정 ProgressBar 컨트롤 만들기

  1. Visual C#에서 새 Windows 컨트롤 라이브러리 프로젝트를 만들려면 다음 단계를 수행합니다.

    1. Microsoft Visual Studio를 시작합니다.

    2. 파일 메뉴에서 새로 만들기를 가리킨 다음 프로젝트를 클릭합니다.

    3. 새 프로젝트 대화 상자의 프로젝트 형식에서 Visual C#을 클릭한 다음 템플릿에서 Windows Forms 제어 라이브러리 클릭합니다.

    4. 이름 상자에 SmoothProgressBar를 입력하고 확인을 클릭합니다.

    5. Project Explorer 기본 클래스 모듈의 이름을 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 Forms 애플리케이션을 클릭한 다음 확인을 클릭합니다.

  3. 다음 단계에 따라 SmoothProgressBar 컨트롤의 두 인스턴스를 양식에 추가합니다.

    1. 도구 메뉴에서 도구 상자 항목 선택을 클릭합니다.

    2. .NET Framework 구성 요소 탭을 클릭합니다.

    3. 찾아보기를 클릭한 다음 사용자 지정 ProgressBar 컨트롤 만들기 섹션에서 만든 SmoothProgressBar.dll 파일을 찾습니다.

    4. 확인을 클릭합니다.

      참고

      SmoothProgressBar 컨트롤이 도구 상자에 추가됩니다.

    5. SmoothProgressBar 컨트롤의 두 인스턴스를 도구 상자에서 Windows 애플리케이션 프로젝트의 기본 형식으로 끌어옵니다.

  4. 도구 상자에서 폼으로 타이머 컨트롤을 끌어옵니다.

  5. 타이머 컨트롤의 Tick 이벤트에 다음 코드를 추가합니다.

    if (this.smoothProgressBar1.Value > 0)
    {
        this.smoothProgressBar1.Value--;
        this.smoothProgressBar2.Value++;
    }
    else
    {
        this.timer1.Enabled = false;
    }
    
  6. 도구 상자에서 폼으로 단추 컨트롤을 끕니다.

  7. Button 컨트롤의 Click 이벤트에 다음 코드를 추가합니다.

    this.smoothProgressBar1.Value = 100;
    this.smoothProgressBar2.Value = 0;
    
    this.timer1.Interval = 1;
    this.timer1.Enabled = true;
    
  8. 디버그 메뉴에서 시작을 클릭하여 샘플 프로젝트를 실행합니다.

  9. 단추를 클릭합니다.

    참고

    두 개의 진행률 표시기에서 텍스트 진행률을 표시합니다. 한 진행률 표시기에서는 진행률을 증가하는 방식으로 표시하고, 다른 진행률 표시기에서는 진행률을 감소 또는 카운트다운 방식으로 표시합니다.