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

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

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

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

감사.



답변

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

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);
    }
}

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


답변

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

샘플 결과

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

여기에 이미지 설명 입력

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

여기에 이미지 설명 입력

어떻게

먼저 다음을 수행하지 않은 경우이를 포함합니다. 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 = 경고 (노란색).

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


답변

이 질문에 대한 답으로 찾을 수있는 가장 많이 사용되는 코드의 깜박임없는 버전입니다. 그 치명적인 답변의 포스터에 대한 모든 크레딧. 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);
            }
        }
    }
}


답변

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

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

pgs.ForeColor = Color.Red;

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

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

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


답변

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#


답변

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);
    }
}


답변

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

  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);
  }

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

마크