진행률 표시 줄에서 두 가지 작업을하고 싶습니다.
- 녹색을 빨간색으로 변경하십시오.
- 블록을 제거하고 단색으로 만듭니다.
이 두 가지를 달성하는 방법에 대한 정보는 대단히 감사 할 것입니다!
감사.
진행률 표시 줄에서 두 가지 작업을하고 싶습니다.
이 두 가지를 달성하는 방법에 대한 정보는 대단히 감사 할 것입니다!
감사.
답변:
이전 답변은 비주얼 스타일에서 작동하지 않는 것으로 보입니다. 자신 만의 클래스를 만들거나 진행률 표시 줄을 확장해야 할 것입니다.
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 = 경고 (노란색).
도움이 되었기를 바랍니다.
public const uint PBM_SETSTATE = 0x0410; // 1040
이 질문에 대한 답으로 찾을 수있는 가장 많이 사용되는 코드의 깜박임없는 버전입니다. 그 치명적인 답변의 포스터에 대한 모든 크레딧. 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의 솔루션에서 한 줄을 변경했습니다).
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#
LinearGradientBrush
rec 너비를 0 으로 읽기 때문에 값이 4 에 도달하면 오류가 발생합니다. 패널이나 패딩 뭔가 (당신이 테두리를 원하는 경우) 만들기 rec.Width = (int)((rec.Width * scaleFactor) - 4)
에rec.Width = (int)(rec.Width * scaleFactor) + 1
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);
}
도움이 되었기를 바랍니다.
마크
편집하다
녹색 블록 기반 프로그램 막대가있는 XP 테마를 사용하는 소리로. UI 스타일을 Windows 클래식으로 전환하고 다시 테스트 해보십시오. 그러나 모든 UI 스타일에서 원하는 작업을 수행하려면 고유 한 OnPaint 이벤트를 구현해야 할 수 있습니다.
또는 다른 사람이 지적했듯이 애플리케이션의 VisualStyles를 비활성화하십시오.
실물
내가 아는 한 진행률 표시 줄의 렌더링은 선택한 Windows 테마 스타일 (win2K, xp, vista)과 함께 인라인으로 발생합니다.
속성을 설정하여 색상을 변경할 수 있습니다.
ProgressBar.ForeColor
하지만 더 많이 할 수 있을지 모르겠습니다 ...
인터넷 검색을 좀 해
MS KB에서 "부드러운"진행률 표시 줄을 만드는 방법에 대한 기사가 있습니다.
메시지 PBM_SETBARCOLOR를 사용해보십시오. SendMessage로 트릭을 수행해야합니다.
예제는 http://www.vbforums.com/showthread.php?t=248721 을 참조 하십시오 .
이 모든 방법이 저에게는 작동하지 않지만이 방법을 사용하면 색상 문자열로 변경할 수 있습니다.
이 코드는 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"라는 이름이 사용되는 곳에서 자신의 진행률 표시 줄 이름으로 바꿉니다. 다른 인수로이 이벤트를 트리거 할 수도 있습니다. 내부 괄호가 어딘가에 있는지 확인하십시오.
변경 Color
및 Value
(즉시 변경)
넣어 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
}
}
pBar.Value = pBar.Maximum;
및 SendMessage(pBar.Handle, 1040, (IntPtr)(int)Color.Green, IntPtr.Zero);
올바른 새 색상을 표시하는 진행의 조건 신체의 내부.
Јοеу : 인용구 : 일반적으로 진행률 표시 줄은 테마가 있거나 사용자의 색상 기본 설정을 따릅니다. 따라서 색상을 변경하려면 비주얼 스타일을 끄고ForeColor
컨트롤을 직접 하거나 그려야합니다.
블록 대신 연속 스타일의 경우 Style
속성을 설정할 수 있습니다 .
pBar.Style = ProgressBarStyle.Continuous;
ProgressBarStyle.Continuous 대 Blocks는 VistualStyles를 활성화하면 쓸모가 없습니다 ...
블록 (들)은 비주얼 스타일이 비활성화 된 상태에서만 작동합니다 ...이 모든 것을 논점으로 렌더링합니다 (사용자 정의 진행 색상과 관련하여) vistual 스타일이 비활성화 된 상태에서 ... 진행률 표시 줄은 앞색을 기준으로 색상이 지정되어야합니다.
William Daniel의 대답 (비주얼 스타일이 활성화되어 있으므로 ForeColor가 스타일없이 평평하지 않을 것임)과 Barry의 대답 (진행률 표시 줄의 사용자 지정 텍스트에 대한)의 조합을 사용했습니다. ProgressBar에 텍스트를 넣는 방법은 무엇입니까?
빨간색으로 아래로 수직 막대 :
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);
}
}
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 값의 진행률 표시 줄을 표시하지 않는 문제를 수정하기 위해 @ 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();
}
}
}
}
}
진행률 표시 줄 내부에 사각형을 그리고 진행률의 현재 값에 따라 너비를 설정하면됩니다. 나는 또한 오른쪽에서 왼쪽으로 진행에 대한 지원을 추가했습니다. 이렇게하면 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);
}
}
}
가장 간단한 해결책은 빠른 수정일 뿐이지 만 Program.cs에서 Application.EnableVisualStyles ()를 삭제하거나 주석 처리하거나 Main 함수를 포함하는 부분의 이름을 지정할 수 있습니다. 그 후에 progressBar.ForeColor = Color.TheColorYouDesire;
static void Main()
{
//Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
편집 : 두 분에서 내가 대를 시작하고 훨씬 더 나은 응답으로 구타당한 구문을 확인하는 데 걸렸습니다. 나는이 사이트를 좋아한다.
progressBar1 = new ProgressBar();
progressBar1.ForeColor = Color.Red;