Cómo cambiar el color de la barra de progreso en C # .NET 3.5?

Me gustaría hacer dos cosas en mi barra de progreso.

  1. Cambie el color verde a rojo.
  2. Retire los bloques y hágala de un color.

¡Cualquier información sobre esas dos cosas que me pregunto cómo lograr será muy bien recibida!

Gracias.

Dado que las respuestas anteriores no parecen funcionar con estilos visuales. Probablemente necesites crear tu propia clase o extender la barra de progreso:

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 actualizado para hacer que la barra de progreso use el estilo visual para el fondo

De acuerdo, me tomó un tiempo leer todas las respuestas y enlaces. Esto es lo que obtuve de ellos:

Resultados de muestra

La respuesta aceptada deshabilita los estilos visuales, le permite establecer el color a cualquier cosa que desee, pero el resultado se ve claro:

enter image description here

Usando el siguiente método, puedes obtener algo como esto en su lugar:

enter image description here

Cómo

Primero, incluya esto si no lo ha hecho: using System.Runtime.InteropServices;

En segundo lugar, puede crear esta nueva clase o poner su código en una clase static no 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); } } 

Ahora, para usarlo, simplemente llame:

ModifyProgressBarColor.SetState(progressBar1, 2);

Tenga en cuenta el segundo parámetro en SetState, 1 = normal (verde); 2 = error (rojo); 3 = advertencia (amarillo).

¡Espero eso ayude!

Esta es una versión sin parpadeo del código más aceptado que puede encontrar como respuestas a esta pregunta. Todo el crédito a los carteles de esas fabulosas respuestas. Gracias Dusty, Chris, Matt y Josh!

Al igual que la solicitud de “Fueled” en uno de los comentarios, también necesitaba una versión que se comportara un poco más … profesional. Este código mantiene los estilos como en el código anterior, pero agrega una imagen fuera de la pantalla y el almacenamiento en búfer de gráficos (y elimina el objeto gráfico correctamente).

Resultado: todo lo bueno, y sin parpadeo. 🙂

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

En el diseñador, solo necesita establecer la propiedad ForeColor al color que desee. En el caso de Red, hay un color predefinido para él.

Para hacerlo en el código (C #) haz esto:

 pgs.ForeColor = Color.Red; 

Editar : Ah sí, también establece el estilo en continuo. En código, así:

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

Otra edición: también deberá eliminar la línea que dice Application.EnableVisualStyles() de su Program.cs (o similar). Si no puedes hacer esto porque quieres que el rest de la aplicación tenga estilos visuales, entonces te sugiero que pintes el control tú mismo o pases a WPF, ya que este tipo de cosas es fácil con WPF. Puede encontrar un tutorial sobre el propietario dibujando una barra de progreso en codeplex

Modificación a la respuesta de dustyburwell. (No tengo suficientes representantes para editarlo). Al igual que su respuesta, funciona con “Estilos visuales” habilitados. Puede establecer la propiedad ForeColor de la barra de progreso en la vista de diseño de cualquier forma.

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

Utilizando las respuestas de Matt Blaine y Chris Persichetti, he creado una barra de progreso que se ve un poco más agradable al tiempo que permite una selección infinita de colores (básicamente, cambié una línea en la solución 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

¡Puedes usar cualquier gradiente que quieras!

Descargar

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

Acabo de poner esto en una clase 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 eso ayude,

Bagazo

Por lo general, la barra de progreso tiene un tema o respeta las preferencias de color del usuario. Por lo tanto, para cambiar el color, debe desactivar los estilos visuales y establecer ForeColor o dibujar el control usted mismo.

En cuanto al estilo continuo en lugar de bloques, puede establecer la propiedad Style :

 pBar.Style = ProgressBarStyle.Continuous; 

EDITAR

Por el sonido de las cosas, estás usando el XP Theme, que tiene la barra de progreso basada en bloques verdes. Intente cambiar el estilo de su interfaz de usuario a Windows Classic y vuelva a probar, pero es posible que necesite implementar su propio evento OnPaint para que haga lo que quiera en todos los estilos de interfaz de usuario.

O, como señaló otra persona, desactive VisualStyles para su aplicación.

Original

Por lo que yo sé, la representación de la barra de progreso sucede en línea con el estilo de tema de Windows que ha elegido (win2K, xp, vista)

Puede cambiar el color estableciendo la propiedad

 ProgressBar.ForeColor 

No estoy seguro de que puedas hacer mucho más sin embargo …

hace algo de google

Hay un artículo aquí de MS KB sobre la creación de una barra de progreso “Suave”

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

Le sugiero que también eche un vistazo a este artículo sobre CodeProject: Progress-O-Doom . ¡Es genial!

intenta usar el messsage PBM_SETBARCOLOR, eso debería hacer el truco con SendMessage

Ver http://www.vbforums.com/showthread.php?t=248721 para un ejemplo.

Todos estos métodos no funcionan para mí, pero este método te permite cambiarlo a una cadena de color.

Tenga en cuenta que encontré este código en otro lugar en StackOverflow y lo cambié un poco. Desde entonces, he olvidado dónde encontré este código y no puedo vincularlo por eso, lo siento mucho por eso.

Pero de todos modos, espero que este código ayude a alguien, realmente me ayudó.

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

Donde se usa el nombre “ProgressBar”, reemplácelo con su propio nombre de la barra de progreso. También puedes activar este evento con otros argumentos, solo asegúrate de que esté dentro de los corchetes.

Cambiar el Color y el Value (cambio instantáneo)

Poner using System.Runtime.InteropServices; hasta arriba…

Llamar con ColorBar.SetState(progressBar1, ColorBar.Color.Yellow, myValue);

Noté que si cambias el valor de la barra (qué tan grande es), no cambiará si está en un color diferente al verde predeterminado. Tomé el código de user1032613 y agregué una opción 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 } } 

En caso de que alguien busque otra opción … puede extender un Panel, usarlo como fondo (blanco o lo que sea), agregar otro Panel dentro del mismo para el primer plano (la barra móvil). Entonces tienes control total cambiando el color, etc.

Simplemente haga clic derecho en su proyecto en Visual Basic Solution Explorer (donde están sus archivos vb) y seleccione propiedades en el menú. En la ventana que aparece, anule la selección de “Habilitar estilos visuales de XP” y ahora cuando configure forecolor, debería funcionar ahora.

De acuerdo: Cita: por lo general, la barra de progreso tiene un tema o respeta las preferencias de color del usuario. Por lo tanto, para cambiar el color, debe desactivar los estilos visuales y establecer ForeColor o dibujar el control usted mismo.

En cuanto al estilo continuo en lugar de bloques, puede establecer la propiedad Style :

 pBar.Style = ProgressBarStyle.Continuous; 

ProgressBarStyle.Continuous versus Blocks es inútil con VistualStyles habilitado …

Los bloques solo funcionarán con los estilos visuales desactivados … lo que hace que todo esto sea un punto irrelevante (con respecto al color de progreso personalizado) Con los estilos vistuales desactivados … la barra de progreso se debe colorear en función del color anterior.

Usé una combinación de la respuesta de William Daniel (con estilos visuales habilitados, por lo que ForeColor no será plana sin estilo) y la respuesta de Barry (a texto personalizado en la barra de progreso) de: ¿Cómo pongo texto en ProgressBar?

Barra vertical UP para abajo en color rojo:

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

La barra de progreso de color VB.Net que respeta la respuesta de WXP Visual Styles es …

Comencé con la respuesta de ‘user1032613’ el 3/17/12. Tenga en cuenta que esto ahora es un Módulo, no una clase. A partir de ahí convertí el código, pero se necesitaba más. En particular, el código convertido mostró una función DirectCast para convertir el entero ‘estado’ a un tipo IntPtr que no funcionó.

 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 

Y nuevamente, solo llame a esto en el código de uso con esta línea:

 Call ModifyProgressBarColor.SetState(prb, 2) 

Por cierto, probé otros colores, 0, 4, 5, todos se muestran en verde.

Sé que es demasiado viejo para ser respondido ahora … pero aún así, un pequeño ajuste a la respuesta de @ Daniel para rectificar el problema de no mostrar la barra de progreso de valor cero. Solo dibuja el Progreso solo si el ancho del rectángulo interno es distinto de cero.

Gracias a todos los contribuyentes.

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

Descubrí que esto se puede hacer dibujando un rectángulo dentro de la barra de progreso y estableciendo su ancho de acuerdo con el valor actual del progreso. También agregué soporte para el progreso de derecha a izquierda. De esta manera, no es necesario utilizar la imagen, y dado que Rectnalge.Inflate no se llama, el rectángulo dibujado es más pequeño.

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

Editar: en los dos minuites me llevó disparar vs y comprobar la syntax que me golpearon con respuestas mucho mejores. amo este sitio

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