Como alterar a cor da barra de progresso no c # .net 3. 5?

Eu gostaria de fazer duas coisas na minha barra de progresso.

  1. Mude a cor verde para vermelho.
  2. Remova os blocos e faça em uma cor.

Qualquer informação sobre essas duas coisas eu me pergunto como realizar será muito bem appreaciated!

Obrigado.

Já que as respostas anteriores não parecem funcionar com os estilos visuais. Você provavelmente precisará criar sua própria class ou estender a barra de progresso:

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

EDIT: código atualizado para fazer a barra de progresso usar o estilo visual para o plano de fundo

OK, demorei um pouco para ler todas as respostas e links. Aqui está o que eu tirei deles:

Resultados da Amostra

A resposta aceita desativa os estilos visuais, permite que você defina a cor como quiser, mas o resultado parece simples:

insira a descrição da imagem aqui

Usando o método a seguir, você pode obter algo assim:

insira a descrição da imagem aqui

Como

Primeiro, inclua isto se você não tiver: using System.Runtime.InteropServices;

Segundo, você pode criar essa nova class ou colocar seu código em uma class não- static existente:

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

Agora, para usá-lo, basta ligar:

ModifyProgressBarColor.SetState(progressBar1, 2);

Observe o segundo parâmetro em SetState, 1 = normal (verde); 2 = erro (vermelho); 3 = aviso (amarelo).

Espero que ajude!

Esta é uma versão sem cintilação do código mais aceito que você pode encontrar como respostas para essa pergunta. Todo o crédito para os cartazes dessas respostas fatásticas. Obrigado Dusty, Chris, Matt e Josh!

Como o pedido de “Fueled” em um dos comentários, eu também precisava de uma versão que se comportasse um pouco mais … profissionalmente. Esse código mantém estilos como no código anterior, mas adiciona uma renderização de imagem fora da canvas e um buffer gráfico (e descarta o object gráfico corretamente).

Resultado: tudo de bom e sem cintilação. 🙂

 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); offscreenImage.Dispose(); } } } } 

No designer, você só precisa definir a propriedade ForeColor para qualquer cor que desejar. No caso do Red, há uma cor predefinida para ele.

Para fazer isso no código (c #) faça o seguinte:

 pgs.ForeColor = Color.Red; 

Edit : Ah sim, também defina o estilo para contínuo. No código, assim:

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

Outro Edit: Você também precisará remover a linha que lê Application.EnableVisualStyles() do seu Program.cs (ou similar). Se você não puder fazer isso porque deseja que o resto do aplicativo tenha estilos visuais, sugiro que você mesmo cole o controle ou mude para o WPF, já que esse tipo de coisa é fácil com o WPF. Você pode encontrar um tutorial sobre o proprietário desenhando uma barra de progresso no codeplex

Modificação para a resposta do dustyburwell. (Eu não tenho representante suficiente para editá-lo). Como sua resposta, ele funciona com “Visual Styles” ativado. Você pode apenas definir a propriedade ForeColor da barra de progresso na exibição de design de qualquer formulário.

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

Usando as respostas de Matt Blaine e Chris Persichetti, criei uma barra de progresso que parece um pouco melhor, permitindo a escolha de colors infinitas (basicamente eu mudei uma linha na solução de 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); } } } 

Uso:

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

Resultados

Você pode usar qualquer gradiente que quiser!

Baixar

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

Eu apenas coloquei isso em uma class estática.

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

Espero que ajude,

Marc

Normalmente, a barra de progresso é temática ou homenageia as preferências de colors do usuário. Portanto, para alterar a cor, você precisa desativar estilos visuais e definir ForeColor ou desenhar o controle.

Quanto ao estilo contínuo em vez de blocos, você pode definir a propriedade Style :

 pBar.Style = ProgressBarStyle.Continuous; 

EDITAR

Pelos sons das coisas que você está usando o XP Theme, que tem o bloco verde baseado em prog-bar. Tente inverter seu estilo de interface do usuário para o Windows Classic e testar novamente, mas talvez seja necessário implementar seu próprio evento OnPaint para que ele faça o que quiser em todos os estilos de interface do usuário

Ou, como outra pessoa apontou, desabilite os VisualStyles para o seu aplicativo.

Original

Tanto quanto eu sei, a renderização da barra de progresso acontece em linha com o estilo de tema do windows que você escolheu (win2k, xp, vista)

Você pode mudar a cor, definindo a propriedade

 ProgressBar.ForeColor 

Eu não tenho certeza que você pode fazer muito mais no entanto …

faz algum googling

Há um artigo aqui do MS KB sobre como criar uma barra de progresso “suave”

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

Eu sugiro que você dê também uma olhada neste artigo sobre CodeProject: Progress-O-Doom . É ótimo!

tente usar messsage PBM_SETBARCOLOR, que deve fazer o truque com SendMessage

Veja http://www.vbforums.com/showthread.php?t=248721 para um exemplo.

Todos esses methods não funcionam para mim, mas esse método permite alterá-lo para uma sequência de colors.

Por favor note que eu encontrei este código de algum outro lugar no StackOverflow e o alterei um pouco. Eu já esqueci onde eu encontrei este código e eu não posso ligá-lo por causa disso, sinto muito por isso.

Mas de qualquer maneira eu espero que este código ajude alguém que realmente me ajudou.

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

Onde o nome “ProgressBar” é usado, substitua pelo seu próprio nome da barra de progresso. Você também pode desencadear este evento com outros argumentos apenas certifique-se de seus parênteses dentro de algum lugar.

Alterar Color e Value (alteração instantânea)

Coloque using System.Runtime.InteropServices; no topo …

Chame com ColorBar.SetState(progressBar1, ColorBar.Color.Yellow, myValue);

Notei que, se você alterar o valor da barra (quão grande ela é), ela não será alterada se estiver em uma cor diferente da verde padrão. Eu peguei o código do user1032613 e adicionei uma opção 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 } } 

Apenas no caso de alguém olhar para outra opção …. você pode estender um painel, usá-lo como plano de fundo (branco ou qualquer outro), adicionar outro painel dentro dele para o primeiro plano (a barra de movimento). Então você tem total controle mudando a cor, etc.

Simplesmente clique com o botão direito do mouse no seu projeto no Gerenciador de Soluções do Visual Basic (onde estão seus arquivos vb) e selecione as propriedades no menu. Na janela que aparece, desmarque “Ativar estilos visuais do XP” e, agora, quando definir a cor, ele deve funcionar agora.

Normalmente: A barra de progresso é temática ou homenageia as preferências de colors do usuário. Portanto, para alterar a cor, você precisa desativar estilos visuais e definir ForeColor ou desenhar o controle.

Quanto ao estilo contínuo em vez de blocos, você pode definir a propriedade Style :

 pBar.Style = ProgressBarStyle.Continuous; 

ProgressBarStyle.Continuous versus Blocks é inútil com o VistualStyles ativado …

O (s) bloco (s) só funciona com estilos visuais desativados … o que torna tudo isso um ponto discutível (com relação à cor personalizada do progresso) Com os estilos exibidos desativados … a barra de progresso deve ser colorida com base no forecolor.

Eu usei uma combinação da resposta de William Daniel (com estilos visuais ativados, para que o ForeColor não fosse apenas plano sem estilo) e a resposta de Barry (para texto personalizado na barra de progresso) de: Como coloco texto em ProgressBar?

Barra vertical para cima para baixo na cor vermelha:

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

A barra de progresso colorida VB.Net, que respeita a resposta dos estilos visuais WXP, é …

Comecei com a resposta de ‘user1032613’ em 17/03/12. Note que este é agora um módulo, não uma class. De lá eu converti o código, mas mais era necessário. Em particular, o código convertido mostrou uma function DirectCast para converter o inteiro “state” em um tipo IntPtr que não funcionava.

 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  _ Private Function SendMessage(hWnd As IntPtr, Msg As UInteger, w As IntPtr, l As IntPtr) As IntPtr End Function  _ 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 

E mais uma vez basta chamar isso no código usando esta linha:

 Call ModifyProgressBarColor.SetState(prb, 2) 

BTW – eu tentei outras colors – 0, 4, 5 – todos eles apenas exibidos em verde.

Eu sei que é muito antigo para ser respondido agora .. mas ainda assim, um pequeno ajuste para a resposta de @ Daniel para corrigir o problema de não mostrar barra de progresso com valor zero. Apenas desenhe o Progresso apenas se a largura do retângulo interno for diferente de zero.

Obrigado a todos os contribuintes.

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

Descobri que isso pode ser feito desenhando um retângulo dentro da barra de progresso e definindo sua largura de acordo com o valor atual do progresso. Eu também adicionei suporte para o progresso da direita para a esquerda. Dessa forma, você não precisa usar a Imagem e, como o Rectnalge.Inflate não é chamado, o retângulo desenhado é menor.

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

Edit: nos dois minuites levei-me a triggersr vs e verificar a syntax fui espancado com respostas muito melhores. Eu amo este site.

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