C # .NET 3.5에서 진행률 표시 줄의 색상을 변경하는 방법은 무엇입니까?


92

진행률 표시 줄에서 두 가지 작업을하고 싶습니다.

  1. 녹색을 빨간색으로 변경하십시오.
  2. 블록을 제거하고 단색으로 만듭니다.

이 두 가지를 달성하는 방법에 대한 정보는 대단히 감사 할 것입니다!

감사.

답변:


83

이전 답변은 비주얼 스타일에서 작동하지 않는 것으로 보입니다. 자신 만의 클래스를 만들거나 진행률 표시 줄을 확장해야 할 것입니다.

public class NewProgressBar : ProgressBar
{
    public NewProgressBar()
    {
        this.SetStyle(ControlStyles.UserPaint, true);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        Rectangle rec = e.ClipRectangle;

        rec.Width = (int)(rec.Width * ((double)Value / Maximum)) - 4;
        if(ProgressBarRenderer.IsSupported)
           ProgressBarRenderer.DrawHorizontalBar(e.Graphics, e.ClipRectangle);
        rec.Height = rec.Height - 4;
        e.Graphics.FillRectangle(Brushes.Red, 2, 2, rec.Width, rec.Height);
    }
}

편집 : 진행률 표시 줄이 배경에 비주얼 스타일을 사용하도록 코드를 업데이트했습니다.


2
덕분에 내 솔루션에서 작업 할 수있었습니다.
Irwin

정말 멋져요, 고마워요. e.ClipRectangle로 지정된 영역 대신 매번 전체 컨트롤을 다시 칠하도록 변경했지만 현재 작업중인 작업에 도움이되었습니다. 그렇지 않으면 컨트롤의 일부만 다른 창이나 화면 가장자리에 의해 무효화 된 후 올바르게 다시 그려지지 않았습니다.
Matt Blaine

@Matt Blaine : 수정 사항을 답변에 대한 편집으로 게시 해 주시겠습니까? 나는 당신의 완전한 솔루션에 관심이있는 충분한 사람들이있을 것이라고 믿습니다.
Marek

@Marek 방금 귀하의 의견을 발견했습니다. 답변을 수정할 수있는 담당자가 부족하여 직접 게시했습니다. 감사. stackoverflow.com/questions/778678/…
Matt Blaine

3
나는 이것이 오래되었다는 것을 압니다. 그리고 나는 이것이 nit라는 것을 알고 있습니다 (Minimum은 거의 항상 0이기 때문에); 그러나 폭 스케일 팩터는 (((double) Value-(double) Minimum) / ((double) Maximum-(double) Minimum)) 이어야 항문 유지력이 정확합니다. :)
Jesse Chisholm

122

좋아, 모든 답변과 링크를 읽는 데 시간이 걸렸습니다. 내가 그들로부터 얻은 것은 다음과 같습니다.

샘플 결과

허용되는 대답은 시각적 스타일을 비활성화하고 원하는 색상으로 설정할 수 있지만 결과는 평범하게 보입니다.

여기에 이미지 설명 입력

다음 방법을 사용하면 대신 다음과 같은 결과를 얻을 수 있습니다.

여기에 이미지 설명 입력

어떻게

먼저 다음을 수행하지 않은 경우이를 포함합니다. using System.Runtime.InteropServices;

둘째,이 새 클래스를 만들거나 기존의 static비 제네릭 클래스 에 해당 코드를 넣을 수 있습니다 .

public static class ModifyProgressBarColor
{
    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
    static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr w, IntPtr l);
    public static void SetState(this ProgressBar pBar, int state)
    {
        SendMessage(pBar.Handle, 1040, (IntPtr)state, IntPtr.Zero);
    }
}

이제 사용하려면 다음을 호출하십시오.

progressBar1.SetState(2);

SetState의 두 번째 매개 변수는 1 = 정상 (녹색)입니다. 2 = 오류 (빨간색); 3 = 경고 (노란색).

도움이 되었기를 바랍니다.


18
확장 메서드를 만들었으므로 호출은 progressBar1.SetState (2); 그 외에도 훌륭한 답변입니다!
Edgar Hernandez

5
이 기능은 Vista +에서만 사용할 수 있습니다. PBM_SETSTATE 를 검색하여 전체 문서를 볼 수 있습니다 .
조프

아름다운! 감사합니다
sapbucket 2015 년

1
이것은 놀랍지 만 내 진행률 표시 줄이 부분적으로 깨져서 100 % 채워지지 않을 것입니다 ....
노 베르트 보로스

1
public const uint PBM_SETSTATE = 0x0410; // 1040
안드레이 크라 수츠 키

37

이 질문에 대한 답으로 찾을 수있는 가장 많이 사용되는 코드의 깜박임없는 버전입니다. 그 치명적인 답변의 포스터에 대한 모든 크레딧. Dusty, Chris, Matt, Josh에게 감사드립니다!

코멘트 중 하나에서 "Fueled"의 요청처럼, 나는 또한 좀 더 전문적으로 행동하는 버전이 필요했습니다. 이 코드는 이전 코드에서와 같이 스타일을 유지하지만 오프 스크린 이미지 렌더링 및 그래픽 버퍼링을 추가합니다 (그래픽 객체를 적절하게 처리 함).

결과 : 모두 양호하고 깜박임이 없습니다. :)

public class NewProgressBar : ProgressBar
{
    public NewProgressBar()
    {
        this.SetStyle(ControlStyles.UserPaint, true);
    }

    protected override void OnPaintBackground(PaintEventArgs pevent)
    {
        // None... Helps control the flicker.
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        const int inset = 2; // A single inset value to control teh sizing of the inner rect.

        using (Image offscreenImage = new Bitmap(this.Width, this.Height))
        {
            using (Graphics offscreen = Graphics.FromImage(offscreenImage))
            {
                Rectangle rect = new Rectangle(0, 0, this.Width, this.Height);

                if (ProgressBarRenderer.IsSupported)
                    ProgressBarRenderer.DrawHorizontalBar(offscreen, rect);

                rect.Inflate(new Size(-inset, -inset)); // Deflate inner rect.
                rect.Width = (int)(rect.Width * ((double)this.Value / this.Maximum));
                if (rect.Width == 0) rect.Width = 1; // Can't draw rec with width of 0.

                LinearGradientBrush brush = new LinearGradientBrush(rect, this.BackColor, this.ForeColor, LinearGradientMode.Vertical);
                offscreen.FillRectangle(brush, inset, inset, rect.Width, rect.Height);

                e.Graphics.DrawImage(offscreenImage, 0, 0);
            }
        }
    }
}

이것은 Microsoft의 원래 구현에 가장 가깝습니다.
Yakup Ünyılmaz 2013 년

1
블록을 사용 하고 Dispose를 호출하는 것은 실제로 약간 중복됩니다. 그래도 좋은 대답.
Kevin Stricker

1
나는 이것이 오래되었다는 것을 압니다. 그리고 나는 이것이 nit라는 것을 알고 있습니다 (Minimum은 거의 항상 0이기 때문에); 그러나 폭 스케일 팩터는 (((double) Value-(double) Minimum) / ((double) Maximum-(double) Minimum)) 이어야 항문 유지력이 정확합니다. :)
Jesse Chisholm

TextRenderer.DrawText ()를 사용하여 텍스트를 오프 스크린 이미지에 그릴 때 화면의 최종 결과는 픽셀 화되어 똑같은 글꼴을 사용하는 레이블처럼 보이지 않습니다. offscreenimager없이이 모든 것을 e.Graphics에 직접 그리면 정확한 결과를 얻을 수 있습니다 ... 이유가 무엇입니까?
CuriousGeorge

1
네, 비 스케일 블리 팅을 시도했습니다. 모든 것을 내가 필요 단지에 내장되어 있습니다, 그래서 마지막으로, 난 그냥, WPF로 전환.
CuriousGeorge

28

디자이너에서는 ForeColor 속성을 원하는 색상으로 설정하기 만하면됩니다. Red의 경우 미리 정의 된 색상이 있습니다.

코드 (C #)에서 수행하려면 다음을 수행하십시오.

pgs.ForeColor = Color.Red;

편집 : 예, 스타일도 연속으로 설정하십시오. 코드에서 다음과 같습니다.

pgs.Style = System.Windows.Forms.ProgressBarStyle.Continuous;

또 다른 편집 : 또한 Application.EnableVisualStyles()자신의 Program.cs(또는 유사한) 에서 읽는 줄을 제거해야합니다 . 나머지 응용 프로그램이 시각적 스타일을 갖기를 원하기 때문에이 작업을 수행 할 수없는 경우 WPF에서는 이러한 종류의 작업이 쉽기 때문에 컨트롤을 직접 페인팅하거나 WPF로 이동하는 것이 좋습니다. Codeplex 에서 진행률 표시 줄 그리는 소유자에 대한 자습서를 찾을 수 있습니다.


3
Forecolor = red; 배경색 = 파란색; 스타일 = Continious. 내가 그것을 만진 적이처럼 아무것도, 그 체재를 변경하지 않습니다
이반 Prodanov에게

3
bah ... 좋아, 문제가 보인다. 속성과 함께 작동하려면 비주얼 스타일을 비활성화해야합니다. 선택한 테마를 사용하여 그림을 그리는 것입니다. Program.cs에는 Application.EnableVisualStyles ()를 읽는 줄이 있습니다. 해당 줄을 제거하면 작동합니다. 그렇지 않으면 컨트롤을 직접 페인트해야합니다. 다른 옵션은 WPF를 사용하는 것입니다 (가능하다면). 이런 종류의 일을 정말 쉽게 할 수 있기 때문입니다.
dustyburwell 2009

"스스로 칠하는 방법"에 대한 자세한 정보를 알려주세요.
Ivan Prodanov 2009

1
다음은 진행률 표시 줄을 그리는 소유자에 대한 자습서입니다. 이 과정은 코멘트를하기에는 너무 복잡합니다. codeproject.com/KB/cpp/VistaProgressBar.aspx
dustyburwell 2009

1
이 솔루션의 핵심 부분은 Application.EnableVisualStyles ()입니다. 불행히도 이것은 다른 모든 스타일을 깨뜨립니다.
mr.user1065741

16

Matt Blaine과 Chris Persichetti의 답변을 사용하여 무한한 색상 선택을 허용하면서 조금 더 멋지게 보이는 진행률 표시 줄을 만들었습니다 (기본적으로 Matt의 솔루션에서 한 줄을 변경했습니다).

ProgressBarEx :

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;

namespace QuantumConcepts.Common.Forms.UI.Controls
{
    public class ProgressBarEx : ProgressBar
    {
        public ProgressBarEx()
        {
            this.SetStyle(ControlStyles.UserPaint, true);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            LinearGradientBrush brush = null;
            Rectangle rec = new Rectangle(0, 0, this.Width, this.Height);
            double scaleFactor = (((double)Value - (double)Minimum) / ((double)Maximum - (double)Minimum));

            if (ProgressBarRenderer.IsSupported)
                ProgressBarRenderer.DrawHorizontalBar(e.Graphics, rec);

            rec.Width = (int)((rec.Width * scaleFactor) - 4);
            rec.Height -= 4;
            brush = new LinearGradientBrush(rec, this.ForeColor, this.BackColor, LinearGradientMode.Vertical);
            e.Graphics.FillRectangle(brush, 2, 2, rec.Width, rec.Height);
        }
    }
}

용법:

progressBar.ForeColor = Color.FromArgb(255, 0, 0);
progressBar.BackColor = Color.FromArgb(150, 0, 0);

결과

원하는 그라데이션을 사용할 수 있습니다!

다운로드

https://skydrive.live.com/?cid=0EDE5D21BDC5F270&id=EDE5D21BDC5F270%21160&sc=documents#


2
나는 이것이 오래되었다는 것을 압니다. 그리고 나는 이것이 nit라는 것을 알고 있습니다 (Minimum은 거의 항상 0이기 때문에); 그러나 폭 스케일 팩터는 (((double) Value-(double) Minimum) / ((double) Maximum-(double) Minimum)) 이어야 항문 유지력이 정확합니다. :)
Jesse Chisholm 2014 년

귀하의 제안에 대한 답변을 업데이트했습니다.
Josh M.

나는 그것이 오래되었다는 것을 알고 있지만-이 코드는 LinearGradientBrushrec 너비를 0 으로 읽기 때문에 값이 4 에 도달하면 오류가 발생합니다. 패널이나 패딩 뭔가 (당신이 테두리를 원하는 경우) 만들기 rec.Width = (int)((rec.Width * scaleFactor) - 4)rec.Width = (int)(rec.Width * scaleFactor) + 1
MiDri

14

dustyburwell의 대답에 대한 수정. (저는 그것을 직접 편집 할 충분한 담당자가 없습니다.) 그의 대답과 마찬가지로 "비주얼 스타일"이 활성화 된 상태에서 작동합니다. 어떤 폼의 디자인보기에서든 진행률 표시 줄의 ForeColor 속성을 설정할 수 있습니다.

using System;
using System.Windows.Forms;
using System.Drawing;

public class ProgressBarEx : ProgressBar
{
    private SolidBrush brush = null;

    public ProgressBarEx()
    {
        this.SetStyle(ControlStyles.UserPaint, true);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        if (brush == null || brush.Color != this.ForeColor)
            brush = new SolidBrush(this.ForeColor);

        Rectangle rec = new Rectangle(0, 0, this.Width, this.Height);
        if (ProgressBarRenderer.IsSupported)
            ProgressBarRenderer.DrawHorizontalBar(e.Graphics, rec);
        rec.Width = (int)(rec.Width * ((double)Value / Maximum)) - 4;
        rec.Height = rec.Height - 4;
        e.Graphics.FillRectangle(brush, 2, 2, rec.Width, rec.Height);
    }
}

이것은 전경색을 변경하는 데 효과적이지만 기본 ProgressBar 컨트롤은 그렇지 않은 반면 많이 깜박입니다. 이 문제를 해결하는 방법을 아십니까?
힘 입어

4
깜박임을 해결하는 방법을 알아 냈습니다 : SetStyle (ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer, ...)와 같이 사용자 정의 ProgressBar의 ControlStyles에 이중 버퍼링을 추가합니다.
연료 공급 :

나는 이것이 오래되었다는 것을 압니다. 그리고 나는 이것이 nit라는 것을 알고 있습니다 (Minimum은 거의 항상 0이기 때문에); 그러나 폭 스케일 팩터는 (((double) Value-(double) Minimum) / ((double) Maximum-(double) Minimum)) 이어야 항문 유지력이 정확합니다. :)
Jesse Chisholm 2014 년

5

나는 이것을 정적 클래스에 넣었습니다.

  const int WM_USER = 0x400;
  const int PBM_SETSTATE = WM_USER + 16;
  const int PBM_GETSTATE = WM_USER + 17;

  [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
  static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

  public enum ProgressBarStateEnum : int
  {
   Normal = 1,
   Error = 2,
   Paused = 3,
  }

  public static ProgressBarStateEnum GetState(this ProgressBar pBar)
  {
   return (ProgressBarStateEnum)(int)SendMessage(pBar.Handle, PBM_GETSTATE, IntPtr.Zero, IntPtr.Zero);
  }

  public static void SetState(this ProgressBar pBar, ProgressBarStateEnum state)
  {
   SendMessage(pBar.Handle, PBM_SETSTATE, (IntPtr)state, IntPtr.Zero);
  } 

도움이 되었기를 바랍니다.

마크


+1 : 나는 이것이 대부분의 사람들이 빨간색으로 의미하는 것이라고 생각합니다. 오류 상태를 표시합니다.
양자

3

일반적으로 진행률 표시 줄은 테마가 있거나 사용자의 색상 기본 설정을 따릅니다. 따라서 색상을 변경하려면 비주얼 스타일을 끄고ForeColor 컨트롤을 직접 하거나 그려야합니다.

블록 대신 연속 스타일의 경우 Style속성을 설정할 수 있습니다 .

pBar.Style = ProgressBarStyle.Continuous;

2

편집하다

녹색 블록 기반 프로그램 막대가있는 XP 테마를 사용하는 소리로. UI 스타일을 Windows 클래식으로 전환하고 다시 테스트 해보십시오. 그러나 모든 UI 스타일에서 원하는 작업을 수행하려면 고유 한 OnPaint 이벤트를 구현해야 할 수 있습니다.

또는 다른 사람이 지적했듯이 애플리케이션의 VisualStyles를 비활성화하십시오.

실물

내가 아는 한 진행률 표시 줄의 렌더링은 선택한 Windows 테마 스타일 (win2K, xp, vista)과 함께 인라인으로 발생합니다.

속성을 설정하여 색상을 변경할 수 있습니다.

ProgressBar.ForeColor

하지만 더 많이 할 수 있을지 모르겠습니다 ...

인터넷 검색을 좀 해

MS KB에서 "부드러운"진행률 표시 줄을 만드는 방법에 대한 기사가 있습니다.

http://support.microsoft.com/kb/323116


@ Eion, Forecolor = red; 배경색 = 파란색; 스타일 = Continious. 아무것도 바뀌지 않았고, 내가 건드리지 않은 것처럼 유지됩니다.
Ivan Prodanov 2009


2

이 모든 방법이 저에게는 작동하지 않지만이 방법을 사용하면 색상 문자열로 변경할 수 있습니다.

이 코드는 StackOverflow의 다른 곳에서 발견하여 약간 변경했습니다. 나는이 코드를 어디에서 찾았는지 잊어 버렸고 그 때문에 유감스럽게도 연결할 수 없습니다.

그러나 어쨌든 나는이 코드가 정말로 도움이 된 누군가에게 도움이되기를 바랍니다.

private void ProgressBar_MouseDown(object sender, MouseButtonEventArgs e)
    {
        var converter = new System.Windows.Media.BrushConverter();
        var brush = (Brush)converter.ConvertFromString("#FFB6D301");
        ProgressBar.Foreground = brush;
    }

"ProgressBar"라는 이름이 사용되는 곳에서 자신의 진행률 표시 줄 이름으로 바꿉니다. 다른 인수로이 이벤트를 트리거 할 수도 있습니다. 내부 괄호가 어딘가에 있는지 확인하십시오.


잘 했어 .. 나는 ProgressChanged 이벤트 내부를 사용하여 빛에서 어둠으로 이동합니다 ... + 1
BENN1TH

2

변경 ColorValue(즉시 변경)

넣어 using System.Runtime.InteropServices;상단에 ...

전화 ColorBar.SetState(progressBar1, ColorBar.Color.Yellow, myValue);

막대의 값 (크기)을 변경하면 기본 녹색이 아닌 다른 색상이면 변경되지 않습니다. user1032613의 코드를 가져와 Value 옵션을 추가했습니다.

public static class ColorBar
{
    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
    static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr w, IntPtr l);
    public enum Color { None, Green, Red, Yellow }

    public static void SetState(this ProgressBar pBar, Color newColor, int newValue)
    {
        if (pBar.Value == pBar.Minimum)  // If it has not been painted yet, paint the whole thing using defualt color...
        {                                // Max move is instant and this keeps the initial move from going out slowly 
            pBar.Value = pBar.Maximum;   // in wrong color on first painting
            SendMessage(pBar.Handle, 1040, (IntPtr)(int)Color.Green, IntPtr.Zero);
        }
        pBar.Value = newValue;
        SendMessage(pBar.Handle, 1040, (IntPtr)(int)Color.Green, IntPtr.Zero);     // run it out to the correct spot in default
        SendMessage(pBar.Handle, 1040, (IntPtr)(int)newColor, IntPtr.Zero);        // now turn it the correct color
    }

}

2
우리는 플립을했다 pBar.Value = pBar.Maximum;SendMessage(pBar.Handle, 1040, (IntPtr)(int)Color.Green, IntPtr.Zero);올바른 새 색상을 표시하는 진행의 조건 신체의 내부.
DomTheDeveloper

1

누군가 다른 옵션을 찾는 경우를 대비하여 패널을 확장하고, 배경 (흰색 또는 기타)으로 사용하고, 전경 (이동 막대)을 위해 내부에 다른 패널을 추가 할 수 있습니다. 그런 다음 색상 등을 완전히 제어 할 수 있습니다.


1

Visual Basic 솔루션 탐색기 (vb 파일이있는 위치)에서 프로젝트를 마우스 오른쪽 단추로 클릭하고 메뉴에서 속성을 선택하기 만하면됩니다. 팝업 창에서 "XP Visual Styles 활성화"를 선택 해제하면 이제 forecolor를 설정할 때 작동합니다.


0

Јοеу : 인용구 : 일반적으로 진행률 표시 줄은 테마가 있거나 사용자의 색상 기본 설정을 따릅니다. 따라서 색상을 변경하려면 비주얼 스타일을 끄고ForeColor 컨트롤을 직접 하거나 그려야합니다.

블록 대신 연속 스타일의 경우 Style속성을 설정할 수 있습니다 .

pBar.Style = ProgressBarStyle.Continuous;

ProgressBarStyle.Continuous 대 Blocks는 VistualStyles를 활성화하면 쓸모가 없습니다 ...

블록 (들)은 비주얼 스타일이 비활성화 된 상태에서만 작동합니다 ...이 모든 것을 논점으로 렌더링합니다 (사용자 정의 진행 색상과 관련하여) vistual 스타일이 비활성화 된 상태에서 ... 진행률 표시 줄은 앞색을 기준으로 색상이 지정되어야합니다.

William Daniel의 대답 (비주얼 스타일이 활성화되어 있으므로 ForeColor가 스타일없이 평평하지 않을 것임)과 Barry의 대답 (진행률 표시 줄의 사용자 지정 텍스트에 대한)의 조합을 사용했습니다. ProgressBar에 텍스트를 넣는 방법은 무엇입니까?


0

빨간색으로 아래로 수직 막대 :

using System;
using System.Windows.Forms;
using System.Drawing;



public class VerticalProgressBar : ProgressBar
{


    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.Style |= 0x04;
            return cp;

        }
    }
    private SolidBrush brush = null;

    public VerticalProgressBar()
    {
        this.SetStyle(ControlStyles.UserPaint, true);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        if (brush == null || brush.Color != this.ForeColor)
            brush = new SolidBrush(this.ForeColor);

        Rectangle rec = new Rectangle(0, 0, this.Width, this.Height);
        if (ProgressBarRenderer.IsSupported)
        ProgressBarRenderer.DrawVerticalBar(e.Graphics, rec);
        rec.Height = (int)(rec.Height * ((double)Value / Maximum)) - 4;
        rec.Width = rec.Width - 4;
        e.Graphics.FillRectangle(brush, 2, 2, rec.Width, rec.Height);

    } 
}

이것이 문제를 해결하는 방법을 코드에 대한 텍스트 또는 주석으로 설명해 주시겠습니까?
Harrison

나는 이것이 nit라는 것을 알고 있습니다 (Minimum은 거의 항상 0이기 때문에); 그러나 높이 축척 계수는 (((double) Value-(double) Minimum) / ((double) Maximum-(double) Minimum)) 이어야 항문 유지력이 정확합니다. :)
Jesse Chisholm 2014 년

0

WXP Visual Styles 답변을 존중하는 VB.Net 컬러 진행률 표시 줄은 ...

나는 3/17/12에 'user1032613'의 답변으로 시작했습니다. 이것은 이제 클래스가 아니라 모듈입니다. 거기에서 나는 코드를 변환했지만 더 많은 것이 필요했습니다. 특히 변환 된 코드는 '상태'정수를 작동하지 않는 IntPtr 유형으로 변환하는 DirectCast 함수를 보여줍니다.

Imports System.Runtime.InteropServices

Public Module ModifyProgressBarColor

    Private Declare Function SendMessage Lib "User32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Long) As Long

    <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=False)> _
    Private Function SendMessage(hWnd As IntPtr, Msg As UInteger, w As IntPtr, l As IntPtr) As IntPtr
    End Function

    <System.Runtime.CompilerServices.Extension()> _
    Public Sub SetState(pBar As ProgressBar, state As Integer)

        '-- Convert state as integer to type IntPtr
        Dim s As IntPtr
        Dim y As Integer = state
        s = IntPtr.op_Explicit(y)

        '-- Modify bar color
        SendMessage(pBar.Handle, 1040, s, IntPtr.Zero)

    End Sub

End Module

그리고 다시 다음 줄을 사용하여 코드를 호출하십시오.

Call ModifyProgressBarColor.SetState(prb, 2)

BTW-다른 색상을 시도했습니다-0, 4, 5-모두 녹색으로 표시되었습니다.


0

나는 지금 대답하기에는 너무 오래되었다는 것을 알고 있습니다. 그러나 여전히 0 값의 진행률 표시 줄을 표시하지 않는 문제를 수정하기 위해 @ Daniel 의 대답을 약간 조정했습니다 . 내부 사각형의 너비가 0이 아닌 경우에만 진행률을 그립니다.

모든 기여자에게 감사드립니다.

        public class ProgressBarEx : ProgressBar
        {
            public ProgressBarEx()
            {
                this.SetStyle(ControlStyles.UserPaint, true);
            }

            protected override void OnPaintBackground(PaintEventArgs pevent){}
                // None... Helps control the flicker.                

            protected override void OnPaint(PaintEventArgs e)
            {
                const int inset = 2; // A single inset value to control teh sizing of the inner rect.

                using (Image offscreenImage = new Bitmap(this.Width, this.Height))
                {
                    using (Graphics offscreen = Graphics.FromImage(offscreenImage))
                    {
                        Rectangle rect = new Rectangle(0, 0, this.Width, this.Height);

                        if (ProgressBarRenderer.IsSupported)
                            ProgressBarRenderer.DrawHorizontalBar(offscreen, rect);

                        rect.Inflate(new Size(-inset, -inset)); // Deflate inner rect.
                        rect.Width = (int)(rect.Width * ((double)this.Value / this.Maximum));

                        if (rect.Width != 0)
                        {
                            LinearGradientBrush brush = new LinearGradientBrush(rect, this.ForeColor, this.BackColor, LinearGradientMode.Vertical);
                            offscreen.FillRectangle(brush, inset, inset, rect.Width, rect.Height);
                            e.Graphics.DrawImage(offscreenImage, 0, 0);
                            offscreenImage.Dispose();
                        }
                    }
                }
            }
        }

0

진행률 표시 줄 내부에 사각형을 그리고 진행률의 현재 값에 따라 너비를 설정하면됩니다. 나는 또한 오른쪽에서 왼쪽으로 진행에 대한 지원을 추가했습니다. 이렇게하면 Image를 사용할 필요가 없으며 Rectnalge.Inflate가 호출되지 않기 때문에 그려진 사각형이 더 작습니다.

public partial class CFProgressBar : ProgressBar
{
    public CFProgressBar()
    {
        InitializeComponent();
        this.SetStyle(ControlStyles.UserPaint, true);
    }

    protected override void OnPaintBackground(PaintEventArgs pevent) { }

    protected override void OnPaint(PaintEventArgs e)
    {
        double scaleFactor = (((double)Value - (double)Minimum) / ((double)Maximum - (double)Minimum));
        int currentWidth = (int)((double)Width * scaleFactor);
        Rectangle rect;
        if (this.RightToLeftLayout)
        {
            int currentX = Width - currentWidth;
            rect = new Rectangle(currentX, 0, this.Width, this.Height);
        }
        else
            rect = new Rectangle(0, 0, currentWidth, this.Height);

        if (rect.Width != 0)
        {
            SolidBrush sBrush = new SolidBrush(ForeColor);
            e.Graphics.FillRectangle(sBrush, rect);
        }
    }
}

0

가장 간단한 해결책은 빠른 수정일 뿐이지 만 Program.cs에서 Application.EnableVisualStyles ()를 삭제하거나 주석 처리하거나 Main 함수를 포함하는 부분의 이름을 지정할 수 있습니다. 그 후에 progressBar.ForeColor = Color.TheColorYouDesire;

static void Main()
        {
            //Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
         }

-5

편집 : 두 분에서 내가 대를 시작하고 훨씬 더 나은 응답으로 구타당한 구문을 확인하는 데 걸렸습니다. 나는이 사이트를 좋아한다.

        progressBar1 = new ProgressBar();
        progressBar1.ForeColor = Color.Red;

2
작동하지 않습니다. 지금 비어 있습니다. progressBar1.value = 50을 추가했지만 여전히 비어 있습니다.
Ivan Prodanov 2009

최대 값을 설정하려고 했습니까? progressBar1 = 새 ProgressBar (); progressBar1.ForeColor = Color.Red; progressBar1.Maximum = 100;
Fusspawn 2009

2
아니요, 문제는 내 Windows 테마에 있습니다.
Ivan Prodanov 2009

이것이 작동하는지 모르겠지만 Application.EnableVisualThemes (); 그것은 미리 빌드 된 파일 중 하나에 있습니다 (나는 무엇을 기억할 수
없는지

1
Application.EnableVisualStyles () 죄송합니다 테마가 아닙니다
Fusspawn 2009
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.