Come cambiare il colore della barra di avanzamento in C # .NET 3.5?

Mi piacerebbe fare due cose sulla mia barra di avanzamento.

  1. Cambia il colore verde in rosso.
  2. Rimuovere i blocchi e renderli in un unico colore.

Qualsiasi informazione su queste due cose che mi chiedo come ottenere sarà molto apprezzata!

Grazie.

Poiché le risposte precedenti non sembrano funzionare con Visual Styles. Probabilmente dovrai creare la tua class o estendere la barra di avanzamento:

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

MODIFICA: codice aggiornato per far sì che la barra di avanzamento usi lo stile visivo per lo sfondo

OK, mi ci è voluto un po ‘per leggere tutte le risposte e i collegamenti. Ecco cosa ho ottenuto da loro:

Risultati del campione

La risposta accettata disabilita gli stili visivi, ti consente di impostare il colore su tutto ciò che desideri, ma il risultato sembra chiaro:

inserisci la descrizione dell'immagine qui

Utilizzando il seguente metodo, puoi ottenere qualcosa come questo:

inserisci la descrizione dell'immagine qui

Come

Innanzitutto, includilo se non lo hai: using System.Runtime.InteropServices;

In secondo luogo, puoi creare questa nuova class o inserire il codice in una class static non generica esistente:

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

Ora, per usarlo, basta chiamare:

ModifyProgressBarColor.SetState(progressBar1, 2);

Notare il secondo parametro in SetState, 1 = normale (verde); 2 = errore (rosso); 3 = avviso (giallo).

Spero che sia d’aiuto!

Questa è una versione senza sfarfallio del codice più accettato che puoi trovare come risposta a questa domanda. Tutto merito ai poster di quelle risposte fatastiche. Grazie Dusty, Chris, Matt e Josh!

Come nella richiesta di “Fueled” in uno dei commenti, avevo anche bisogno di una versione che si fosse comportata un po ‘di più … professionale. Questo codice mantiene gli stili come nel codice precedente, ma aggiunge un rendering di immagine fuori schermo e un buffering grafico (e dispone l’object grafico correttamente).

Risultato: tutto bene e niente sfarfallio. 🙂

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

Nella finestra di progettazione, devi solo impostare la proprietà ForeColor su qualsiasi colore desideri. Nel caso di Red, c’è un colore predefinito per questo.

Per farlo in codice (C #) fai questo:

 pgs.ForeColor = Color.Red; 

Modifica : Oh sì, anche impostare lo stile su continuo. Nel codice, come questo:

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

Un’altra modifica: dovrai anche rimuovere la riga che legge Application.EnableVisualStyles() dal tuo Program.cs (o simile). Se non puoi farlo perché vuoi che il resto dell’applicazione abbia stili visivi, allora suggerirei di dipingere il controllo da solo o passare a WPF poiché questo tipo di cose è facile con WPF. Puoi trovare un’esercitazione sul proprietario che disegna una barra di avanzamento su codeplex

Modifica alla risposta di dustyburwell. (Non ho abbastanza rep per modificarlo da solo.) Come la sua risposta, funziona con “Visual Styles” abilitato. Puoi semplicemente impostare la proprietà ForeColor della progressbar in qualsiasi vista di progettazione del modulo.

 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 le risposte di Matt Blaine e Chris Persichetti ho creato una barra di progresso che sembra un po ‘più carina pur consentendo una scelta infinita di colors (in pratica ho cambiato una riga nella soluzione di 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); 

risultati

Puoi usare qualsiasi gradiente che ti piace!

Scaricare

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

Ho appena messo questo in una class statica.

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

Spero che sia d’aiuto,

Marc

Di solito la barra di avanzamento è a tema o onora le preferenze di colore dell’utente. Quindi, per cambiare il colore devi distriggersre gli stili di visualizzazione e impostare ForeColor o disegnare il controllo da solo.

Per quanto riguarda lo stile continuo invece dei blocchi, puoi impostare la proprietà Style :

 pBar.Style = ProgressBarStyle.Continuous; 

MODIFICARE

Dai suoni delle cose che stai usando il tema XP che ha il prog-bar basato sul blocco verde. Prova a rivoltare lo stile dell’interfaccia utente su Windows Classic e prova di nuovo, ma potresti aver bisogno di implementare il tuo evento OnPaint per ottenere ciò che desideri in tutti gli stili dell’interfaccia utente

O come indicato da qualcun altro, disabilita VisualStyles per la tua applicazione.

Originale

Per quanto ne so, il rendering della barra di avanzamento avviene in linea con lo stile del tema di Windows che hai scelto (win2K, xp, vista)

Puoi cambiare il colore impostando la proprietà

 ProgressBar.ForeColor 

Non sono sicuro che tu possa fare molto di più però …

fa un po ‘googling

C’è un articolo qui da MS KB sulla creazione di una barra di avanzamento “Smooth”

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

Ti suggerisco di dare anche un’occhiata a questo articolo su CodeProject: Progress-O-Doom . È ottimo!

prova a usare messsage PBM_SETBARCOLOR, che dovrebbe fare il trucco con SendMessage

Vedi http://www.vbforums.com/showthread.php?t=248721 per un esempio.

Tutti questi metodi non funzionano per me, ma questo metodo consente di cambiarlo in una stringa di colors.

Si prega di notare che ho trovato questo codice da qualche altra parte su StackOverflow e l’ho cambiato un po ‘. Da allora ho dimenticato dove ho trovato questo codice e non riesco a collegarlo a causa di questo mi dispiace per quello.

Ma comunque spero che questo codice aiuti qualcuno che mi ha davvero aiutato.

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

Dove viene utilizzato il nome “ProgressBar” sostituire con il proprio nome della barra di avanzamento. Puoi anche triggersre questo evento con altri argomenti assicurandoti solo le parentesi interne da qualche parte.

Cambia Color e Value (cambio istantaneo)

Metti using System.Runtime.InteropServices; in cima …

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

Ho notato che se si modifica il valore della barra (quanto è grande), non cambierà se si trova in un colore diverso dal verde predefinito. Ho preso il codice di user1032613 e ho aggiunto un’opzione 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 } } 

Nel caso in cui qualcuno cerchi un’altra opzione … puoi estendere un Pannello, usarlo come sfondo (bianco o altro), aggiungere un altro Pannello al suo interno per il primo piano (la barra mobile). Quindi hai il controllo totale cambiando il colore, ecc.

È sufficiente fare clic con il pulsante destro del mouse sul progetto in Esplora soluzioni di Visual Basic (dove si trovano i file VB) e selezionare le proprietà dal menu. Nella finestra che si apre deseleziona “Abilita stili visivi XP” e ora quando imposti forecolor, dovrebbe funzionare ora.

Tutto: Quote: in genere la barra di avanzamento è a tema o onora le preferenze di colore dell’utente. Quindi, per cambiare il colore devi distriggersre gli stili di visualizzazione e impostare ForeColor o disegnare il controllo da solo.

Per quanto riguarda lo stile continuo invece dei blocchi, puoi impostare la proprietà Style :

 pBar.Style = ProgressBarStyle.Continuous; 

ProgressBarStyle.Continuous versus Blocks è inutile con VistualStyles abilitato …

I blocchi funzioneranno solo con gli stili di visualizzazione disabilitati … il che rende tutto questo un punto controverso (per quanto riguarda il colore di avanzamento personalizzato) Con gli stili di selezione disabilitati … la barra di avanzamento dovrebbe essere colorata in base al colore predefinito.

Ho usato una combinazione della risposta di William Daniel (con gli stili di visualizzazione triggersti, quindi ForeColor non sarà semplicemente piatto senza stile) e la risposta di Barry (al testo personalizzato sulla barra di avanzamento) da: Come inserisco il testo su ProgressBar?

Barra verticale SU per giù in colore rosso:

 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 di avanzamento colorata VB.Net che rispetta la risposta degli stili visivi WXP è …

Ho iniziato con la risposta di “user1032613” il 17/3/12. Nota che questo è ora un modulo, non una class. Da lì ho convertito il codice, ma ne avevo bisogno di altro. In particolare il codice convertito mostrava una funzione DirectCast per convertire il intero ‘stato’ in un tipo IntPtr che non funzionava.

 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 di nuovo basta chiamare questo nel codice usando con questa linea:

 Call ModifyProgressBarColor.SetState(prb, 2) 

BTW – Ho provato altri colors – 0, 4, 5 – sono tutti visualizzati in verde.

So che è troppo vecchio per poter rispondere ora .. ma ancora, un piccolo aggiustamento per la risposta di @ Daniel per rettificare il problema di non mostrare la barra di progresso con valore zero. Basta disegnare il progresso solo se la larghezza del rettangolo interno è risultata diversa da zero.

Grazie a tutti i contributori.

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

Ho trovato che questo può essere fatto disegnando un rettangolo all’interno della barra di avanzamento e impostarne la larghezza in base al valore corrente dello stato di avanzamento. Ho anche aggiunto il supporto per il progresso da destra a sinistra. In questo modo non hai bisogno di usare l’Immagine, e dal momento che Rectnalge.Inflate non è chiamato il rettangolo disegnato è più piccolo.

 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: nei due minuti mi ci sono voluti per sparare vs e controllare la syntax mi è stato battuto con risposte molto migliori. amo questo sito

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