Eu gostaria de fazer duas coisas na minha barra de progresso.
- Mude a cor verde para vermelho.
- Remova os blocos e faça em uma cor.
Qualquer informação sobre essas duas coisas que me pergunto como realizar será muito apreciada!
Obrigado.
Eu gostaria de fazer duas coisas na minha barra de progresso.
Qualquer informação sobre essas duas coisas que me pergunto como realizar será muito apreciada!
Obrigado.
Respostas:
Uma vez que as respostas anteriores não parecem funcionar com estilos visuais. Você provavelmente precisará criar sua própria classe 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);
}
}
EDITAR: código atualizado para fazer a barra de progresso usar o estilo visual para o fundo
OK, demorei um pouco para ler todas as respostas e links. Aqui está o que consegui com eles:
Resultados da amostra
A resposta aceita desativa os estilos visuais, permite que você defina a cor que quiser, mas o resultado parece simples:

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

Como
Primeiro, inclua se você não tiver: using System.Runtime.InteropServices;
Em segundo lugar, você pode criar essa nova classe ou colocar seu código em uma staticclasse não genérica 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 chamar:
progressBar1.SetState(2);
Observe o segundo parâmetro em SetState, 1 = normal (verde); 2 = erro (vermelho); 3 = aviso (amarelo).
Espero que ajude!
public const uint PBM_SETSTATE = 0x0410; // 1040
Esta é uma versão sem cintilação do código mais aceito que você pode encontrar como resposta a esta pergunta. Todo o crédito para os cartazes dessas respostas fatasticas. Obrigado Dusty, Chris, Matt e Josh!
Assim 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. Este código mantém os estilos como no código anterior, mas adiciona uma renderização de imagem fora da tela e armazenamento em buffer de gráficos (e descarta o objeto gráfico corretamente).
Resultado: tudo de bom e sem oscilações. :)
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);
}
}
}
}
No designer, você só precisa definir a propriedade ForeColor para a cor que desejar. No caso do vermelho, existe uma cor predefinida para ele.
Para fazer isso em código (C #), faça o seguinte:
pgs.ForeColor = Color.Red;
Edit : Oh yeah, também defina o estilo para contínuo. Em código, como este:
pgs.Style = System.Windows.Forms.ProgressBarStyle.Continuous;
Outra edição: você também precisará remover a linha que lê Application.EnableVisualStyles()de seu Program.cs(ou similar). Se você não pode fazer isso porque deseja que o restante do aplicativo tenha estilos visuais, sugiro pintar o controle você mesmo ou passar para o WPF, pois esse tipo de coisa é fácil com o WPF. Você pode encontrar um tutorial sobre como o proprietário desenha uma barra de progresso no codeplex
Usando as respostas de Matt Blaine e Chris Persichetti, criei uma barra de progresso que parece um pouco melhor, permitindo uma escolha infinita de cores (basicamente, mudei uma linha na solução de 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#
LinearGradientBrushleitura da largura de rec como 0. A correção mais fácil é não fazer o "preenchimento" de 4px no código e colocá-lo em um painel ou algo com preenchimento (se você quiser uma borda) e transformando rec.Width = (int)((rec.Width * scaleFactor) - 4)emrec.Width = (int)(rec.Width * scaleFactor) + 1
Modificação para a resposta de Dustyburwell. (Não tenho representantes suficientes para editar sozinho.) Como sua resposta, funciona com "Estilos visuais" habilitado. Você pode apenas definir a propriedade ForeColor da barra de progresso em qualquer visualização de design do 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);
}
}
Acabei de colocar isso em uma classe 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 respeita as preferências de cor do usuário. Portanto, para alterar a cor, você precisa desligar os estilos visuais e definirForeColor ou desenhar o controle você mesmo.
Quanto ao estilo contínuo em vez de blocos, você pode definir a Stylepropriedade:
pBar.Style = ProgressBarStyle.Continuous;
EDITAR
Pelo som das coisas, você está usando o Tema XP que tem a barra de programação baseada em blocos verdes. Tente mudar seu estilo de interface do usuário para o Windows Classic e teste novamente, mas pode ser necessário implementar seu próprio evento OnPaint para fazer o que você deseja em todos os estilos de interface do usuário
Ou como alguém apontou, desative os VisualStyles para seu aplicativo.
Original
Pelo que 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 alterar a cor definindo a propriedade
ProgressBar.ForeColor
Não tenho certeza se você pode fazer muito mais ...
faz alguma pesquisa no Google
Há um artigo aqui do MS KB sobre como criar uma barra de progresso "Suave"
tente usar o messsage PBM_SETBARCOLOR, que deve funcionar com SendMessage
Consulte http://www.vbforums.com/showthread.php?t=248721 para obter um exemplo.
Todos esses métodos não funcionam para mim, mas este método permite que você altere para uma seqüência de cores.
Observe que encontrei esse código em outro lugar no StackOverflow e o alterei um pouco. Desde então, esqueci onde encontrei este código e não consigo vinculá-lo por causa disso, sinto muito por isso.
Mas, de qualquer forma, espero que este código ajude alguém, ele 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 nome da sua própria barra de progresso. Você também pode acionar este evento com outros argumentos, apenas certifique-se de que ele esteja entre colchetes em algum lugar.
Mudança Colore Value(mudança instantânea)
Coloque using System.Runtime.InteropServices;no topo ...
Ligue com ColorBar.SetState(progressBar1, ColorBar.Color.Yellow, myValue);
Percebi que se você alterar o valor da barra (quão grande ela é), ela não mudará se estiver em uma cor diferente do verde padrão. Peguei o código do user1032613 e adicionei uma opção de valor.
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;e SendMessage(pBar.Handle, 1040, (IntPtr)(int)Color.Green, IntPtr.Zero);dentro do corpo-condição para que o progresso mostrasse a nova cor correta.
Pergunta: Citação: Normalmente, a barra de progresso é temática ou respeita as preferências de cor do usuário. Portanto, para alterar a cor, você precisa desligar os estilos visuais e definirForeColor ou desenhar o controle você mesmo.
Quanto ao estilo contínuo em vez de blocos, você pode definir a Stylepropriedade:
pBar.Style = ProgressBarStyle.Continuous;
ProgressBarStyle.Continuous versus Blocks é inútil com VistualStyles habilitado ...
O (s) bloco (s) só funcionarão com estilos visuais desativados ... o que torna tudo isso um ponto discutível (com relação à cor de progresso personalizada). Com estilos de visitas desativados ... a barra de progresso deve ser colorida com base na cor principal.
Usei uma combinação da resposta de William Daniel (com estilos visuais habilitados, para que o ForeColor não fique apenas plano, sem estilo) e a resposta de Barry (para texto personalizado na barra de progresso) de: Como coloco texto na ProgressBar?
Barra vertical UP For Down 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. Observe que agora isso é um módulo, não uma classe. A partir daí, converti o código, mas era necessário mais. Em particular, o código convertido mostrou uma função DirectCast para converter o inteiro 'estado' em um tipo IntPtr que não funcionou.
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
E, novamente, basta chamar isso no código using com esta linha:
Call ModifyProgressBarColor.SetState(prb, 2)
BTW - eu tentei outras cores - 0, 4, 5 - todas exibiam apenas verde.
Eu sei que é muito antigo para ser respondido agora .. mas ainda assim, um pequeno ajuste no @Daniel resposta 's para corrigir o problema de não mostrar zero, barra de progresso valorizado. 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. Desta forma, você não precisa usar a imagem e, como 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);
}
}
}
Acho que a solução mais simples de todas, é só um conserto rápido, mas você pode deletar, comentar o Application.EnableVisualStyles () do Program.cs, ou entretanto você tem o nome da parte que contém a função Main. Depois disso, você pode alterar livremente a cor da barra de progresso por progressBar.ForeColor = Color.TheColorYouDesire;
static void Main()
{
//Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
Edit: nos dois minutos, demorei para acionar o vs e verificar a sintaxe que recebi com respostas muito melhores. eu amo este site.
progressBar1 = new ProgressBar();
progressBar1.ForeColor = Color.Red;