Me gustaría hacer dos cosas en mi barra de progreso.
- Cambia el color verde a rojo.
- Quita los bloques y hazlo de un color.
¡Cualquier información sobre esas dos cosas que me pregunto cómo lograr será muy apreciada!
Gracias.
Me gustaría hacer dos cosas en mi barra de progreso.
¡Cualquier información sobre esas dos cosas que me pregunto cómo lograr será muy apreciada!
Gracias.
Respuestas:
Dado que las respuestas anteriores no parecen funcionar con Visual Styles. Probablemente necesitará crear su 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 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 en cualquier cosa que desee, pero el resultado parece sencillo:
Usando el siguiente método, puede obtener algo como esto en su lugar:
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 static
clase 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 a:
progressBar1.SetState(2);
Tenga en cuenta el segundo parámetro en SetState, 1 = normal (verde); 2 = error (rojo); 3 = advertencia (amarillo).
¡Espero eso ayude!
public const uint PBM_SETSTATE = 0x0410; // 1040
Esta es una versión sin parpadeos del código más aceptado que puede encontrar como respuesta a esta pregunta. Todo el mérito a los carteles de esas respuestas fatídicas. ¡Gracias Dusty, Chris, Matt y Josh!
Como la solicitud de "Fueled" en uno de los comentarios, también necesitaba una versión que se comportara un poco más ... profesionalmente. Este código mantiene los estilos como en el código anterior, pero agrega un renderizado de imágenes fuera de la pantalla y almacenamiento en búfer de gráficos (y elimina el objeto gráfico correctamente).
Resultado: todo bien 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);
}
}
}
}
En el diseñador, solo necesita establecer la propiedad ForeColor en el color que desee. En el caso del rojo, hay un color predefinido para él.
Para hacerlo en código (C #) haga esto:
pgs.ForeColor = Color.Red;
Editar : Oh sí, también establezca 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()
su Program.cs
(o similar). Si no puede hacer esto porque desea que el resto de la aplicación tenga estilos visuales, le sugiero que pinte el control usted mismo o pase a WPF, ya que este tipo de cosas es fácil con WPF. Puede encontrar un tutorial sobre cómo el propietario dibuja una barra de progreso en el codeplex
Usando las respuestas de Matt Blaine y Chris Persichetti, he creado una barra de progreso que se ve un poco mejor al tiempo que permite una elección de color infinita (básicamente cambié una línea en la solución 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#
LinearGradientBrush
lee el ancho de grabación como 0. La solución más fácil es no hacer el "relleno" de 4px en el código y colocarlo en un panel o algo con relleno (si desea un borde) y se convierte rec.Width = (int)((rec.Width * scaleFactor) - 4)
enrec.Width = (int)(rec.Width * scaleFactor) + 1
Modificación a la respuesta de dustyburwell. (No tengo suficiente representante para editarlo yo mismo). 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 formulario.
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);
}
}
Solo puse 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. Entonces, para cambiar el color, debe desactivar los estilos visuales y configurarForeColor
o dibujar el control usted mismo.
En cuanto al estilo continuo en lugar de bloques, puede establecer la Style
propiedad:
pBar.Style = ProgressBarStyle.Continuous;
EDITAR
Por lo que parece, estás usando el tema XP, que tiene la barra de progreso basada en bloques verdes. Intente cambiar su estilo de interfaz de usuario a Windows Classic y vuelva a realizar la prueba, pero es posible que deba implementar su propio evento OnPaint para que haga lo que desea en todos los estilos de interfaz de usuario
O como alguien más señaló, desactive VisualStyles para su aplicación.
Original
Hasta donde yo sé, la representación de la barra de progreso ocurre en línea con el estilo de tema de Windows que ha elegido (win2K, xp, vista)
Puede cambiar el color configurando la propiedad
ProgressBar.ForeColor
Sin embargo, no estoy seguro de que puedas hacer mucho más ...
busca algo en google
Aquí hay un artículo de MS KB sobre la creación de una barra de progreso "suave".
intente usar el mensaje PBM_SETBARCOLOR, que debería funcionar con SendMessage
Consulte http://www.vbforums.com/showthread.php?t=248721 para ver un ejemplo.
Todos estos métodos no funcionan para mí, pero este método le 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.
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 use el nombre "ProgressBar" reemplácelo con el nombre de su propia barra de progreso. También puede activar este evento con otros argumentos, solo asegúrese de que esté entre corchetes en algún lugar.
Cambiar Color
y Value
(cambio instantáneo)
Poner using System.Runtime.InteropServices;
en la parte superior ...
Llamar con ColorBar.SetState(progressBar1, ColorBar.Color.Yellow, myValue);
Noté que si cambia el valor de la barra (qué tan grande es), entonces no cambiará si está en un color que no sea el 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
}
}
pBar.Value = pBar.Maximum;
y SendMessage(pBar.Handle, 1040, (IntPtr)(int)Color.Green, IntPtr.Zero);
dentro del cuerpo de condición para que el progreso mostrara el nuevo color correcto.
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 XP" y ahora, cuando configure el color de fondo, debería funcionar ahora.
Ojo: Cita: Por lo general, la barra de progreso tiene un tema o respeta las preferencias de color del usuario. Entonces, para cambiar el color, debe desactivar los estilos visuales y configurarForeColor
o dibujar el control usted mismo.
En cuanto al estilo continuo en lugar de bloques, puede establecer la Style
propiedad:
pBar.Style = ProgressBarStyle.Continuous;
ProgressBarStyle.Continuous versus Blocks es inútil con VistualStyles habilitado ...
Los bloques solo funcionarán con los estilos visuales deshabilitados ... lo que hace que todo esto sea un punto discutible (con respecto al color de progreso personalizado) Con los estilos visuales deshabilitados ... la barra de progreso debe ser coloreada según el color anterior.
Usé una combinación de la respuesta de William Daniel (con los estilos visuales habilitados, por lo que ForeColor no solo será plano sin estilo) y la respuesta de Barry (al texto personalizado en la barra de progreso) de: ¿Cómo coloco texto en ProgressBar?
Barra vertical ARRIBA 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 de VB.Net que respeta la respuesta de WXP Visual Styles es ...
Comencé con la respuesta de 'user1032613' el 17/03/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
<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
Y nuevamente simplemente 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 @ Daniel la respuesta de para rectificar el problema de no mostrar la barra de progreso con valor cero. Simplemente dibuje el Progreso solo si se encuentra que el ancho del rectángulo interior no es 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 forma 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);
}
}
}
Creo que la solución más simple de todas, es solo una solución rápida, pero puede eliminar, comentar Application.EnableVisualStyles () de Program.cs, o como quiera que haya nombrado la parte que contiene la función Main. Después de eso, puede cambiar libremente el color de la barra de progreso mediante progressBar.ForeColor = Color.TheColorYouDesire;
static void Main()
{
//Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
Editar: en los dos minutos me tomó encender vs y verificar la sintaxis, me golpearon con respuestas mucho mejores. me encanta este sitio.
progressBar1 = new ProgressBar();
progressBar1.ForeColor = Color.Red;