Comment changer la couleur de la barre de progression dans C # .NET 3.5?

91

J'aimerais faire deux choses sur ma barre de progression.

  1. Changez la couleur verte en rouge.
  2. Retirez les blocs et faites-le dans une seule couleur.

Toute information sur ces deux choses que je me demande comment accomplir sera très appréciée!

Merci.

Ivan Prodanov
la source

Réponses:

82

Étant donné que les réponses précédentes ne semblent pas fonctionner avec les styles visuels. Vous devrez probablement créer votre propre classe ou étendre la barre de progression:

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: code mis à jour pour que la barre de progression utilise le style visuel pour l'arrière-plan

Chris Persichetti
la source
2
Merci pour cela, c'était quelque chose avec lequel je pourrais travailler dans ma solution.
Irwin
C'est vraiment cool, merci. Cela m'a vraiment aidé sur quelque chose sur lequel je travaille en ce moment, même si je l'ai changé pour repeindre tout le contrôle à chaque fois au lieu de simplement la zone spécifiée par e.ClipRectangle. Sinon, il n'a pas été repeint correctement après qu'une partie seulement du contrôle a été invalidée par une autre fenêtre ou le bord de l'écran.
Matt Blaine
@Matt Blaine: Pourriez-vous s'il vous plaît poster votre modification en tant que modification de la réponse? Je pense qu'il y aura suffisamment de personnes intéressées par votre solution complète.
Marek
@Marek Je viens de remarquer votre commentaire. Je n'ai pas assez de représentants pour modifier la réponse, j'ai donc publié la mienne. Merci. stackoverflow.com/questions/778678/…
Matt Blaine
3
Je me rends compte que c'est vieux; et je me rends compte que c'est un nit (parce que le minimum est presque toujours zéro); mais le facteur d'échelle de largeur doit être (((double) Valeur - (double) Minimum) / ((double) Maximum - (double) Minimum)) pour être anal-rétentivement correct. :)
Jesse Chisholm
121

OK, il m'a fallu un certain temps pour lire toutes les réponses et les liens. Voici ce que j'en ai retiré:

Exemples de résultats

La réponse acceptée désactive les styles visuels, elle vous permet de définir la couleur à ce que vous voulez, mais le résultat semble clair:

entrez la description de l'image ici

En utilisant la méthode suivante, vous pouvez obtenir quelque chose comme ceci à la place:

entrez la description de l'image ici

Comment

Tout d'abord, incluez ceci si vous ne l'avez pas fait: using System.Runtime.InteropServices;

Deuxièmement, vous pouvez soit créer cette nouvelle classe, soit placer son code dans une staticclasse non générique existante :

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

Maintenant, pour l'utiliser, appelez simplement:

progressBar1.SetState(2);

Notez le deuxième paramètre dans SetState, 1 = normal (vert); 2 = erreur (rouge); 3 = avertissement (jaune).

J'espère que ça aide!

user1032613
la source
18
Vous avez créé une méthode d'extension, l'appel doit donc être progressBar1.SetState (2); en plus de cela, excellente réponse!
Edgar Hernandez
5
A noter que cela n'est disponible que sur Vista +. Vous pouvez consulter la documentation complète en recherchant PBM_SETSTATE .
Djof
Belle! Merci
sapbucket
1
C'est incroyable, mais ça casse partiellement ma barre de progression, ça ne se remplira jamais à 100% ....
Norbert Boros
1
public const uint PBM_SETSTATE = 0x0410; // 1040
Andrei Krasutski
37

Ceci est une version sans scintillement du code le plus accepté que vous pouvez trouver comme réponses à cette question. Tout le crédit aux affiches de ces réponses fatastiques. Merci Dusty, Chris, Matt et Josh!

Comme la demande de "Fueled" dans l'un des commentaires, j'avais également besoin d'une version qui se comporte un peu plus ... professionnellement. Ce code conserve les styles comme dans le code précédent, mais ajoute un rendu d'image hors écran et une mise en mémoire tampon graphique (et supprime correctement l'objet graphique).

Résultat: tout le bien, et pas de scintillement. :)

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);
            }
        }
    }
}
William Daniel
la source
Eh bien, c'est la plus proche de l'implémentation originale de Microsoft.
Yakup Ünyılmaz
1
Avoir un bloc using et appeler Dispose est en fait un peu redondant. Excellente réponse cependant.
Kevin Stricker
1
Je me rends compte que c'est vieux; et je me rends compte que c'est un nit (parce que le minimum est presque toujours zéro); mais le facteur d'échelle de largeur doit être (((double) Valeur - (double) Minimum) / ((double) Maximum - (double) Minimum)) pour être anal-rétentivement correct. :)
Jesse Chisholm
Lorsque j'utilise TextRenderer.DrawText () pour dessiner du texte dans une image hors écran, le résultat final à l'écran semble pixélisé, et non comme une étiquette utilisant exactement la même police. Dessiner tout cela directement sur e.Graphics sans le Offscreenimager donne le résultat correct cependant ... Des idées pourquoi?
CuriousGeorge
1
Ouais, j'ai essayé de blitting sans mise à l'échelle. Enfin, je viens de passer à WPF, donc tout ce dont j'ai besoin est intégré.
CuriousGeorge
28

Dans le concepteur, il vous suffit de définir la propriété ForeColor sur la couleur de votre choix. Dans le cas du rouge, il existe une couleur prédéfinie pour celui-ci.

Pour le faire dans le code (C #), procédez comme suit:

pgs.ForeColor = Color.Red;

Edit : Oh oui, réglez également le style sur continu. Dans le code, comme ceci:

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

Une autre modification: vous devrez également supprimer la ligne qui lit Application.EnableVisualStyles()dans votre Program.cs(ou similaire). Si vous ne pouvez pas faire cela parce que vous voulez que le reste de l'application ait des styles visuels, alors je vous suggère de peindre le contrôle vous-même ou de passer à WPF car ce genre de chose est facile avec WPF. Vous pouvez trouver un tutoriel sur le dessin par le propriétaire d'une barre de progression sur codeplex

poussiéreux
la source
3
Couleur avant = rouge; Backcolor = bleu; Style = continu. Rien n'a changé, c'est rester comme je ne l'ai jamais touché
Ivan Prodanov
3
bah ... d'accord, je vois le problème. Vous devez désactiver les styles visuels pour que cela fonctionne avec les propriétés. Il s'agit probablement de peindre en utilisant le thème que vous avez sélectionné. Dans Program.cs, il y a une ligne qui lit Application.EnableVisualStyles (). Supprimez cette ligne et cela fonctionnera. Sinon, vous devrez peindre le contrôle vous-même. L'autre option est d'utiliser WPF (si c'est une possibilité), car cela vous permet de faire ce genre de choses très facilement.
dustyburwell
Veuillez me donner plus d'informations sur "Comment le peindre moi-même".
Ivan Prodanov le
1
Voici un tutoriel sur le dessin par le propriétaire d'une barre de progression. Le processus est beaucoup trop compliqué pour un commentaire. codeproject.com/KB/cpp/VistaProgressBar.aspx
dustyburwell
1
C'est dommage Application.EnableVisualStyles () est l'élément clé de cette solution. Malheureusement, cela casse tous les autres styles.
mr.user1065741
16

En utilisant les réponses de Matt Blaine et Chris Persichetti, j'ai créé une barre de progression qui semble un peu plus jolie tout en permettant un choix de couleurs infini (en gros, j'ai changé une ligne dans la solution 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);
        }
    }
}

Usage:

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

Résultats

Vous pouvez utiliser n'importe quel dégradé que vous aimez!

Télécharger

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

Josh M.
la source
2
Je me rends compte que c'est vieux; et je me rends compte que c'est un nit (parce que le minimum est presque toujours zéro); mais le facteur d'échelle de largeur doit être (((double) Valeur - (double) Minimum) / ((double) Maximum - (double) Minimum)) pour être anal-rétentivement correct. :)
Jesse Chisholm
Mise à jour de la réponse avec votre suggestion.
Josh M.
Je sais que c'est vieux, mais - ce code provoquera une erreur une fois qu'il atteindra une valeur de 4, en raison de la LinearGradientBrushlecture de la largeur de rec comme 0. La solution la plus simple est de ne pas faire le "padding" de 4px dans le code et de le placer à la place dans un panneau ou quelque chose avec un rembourrage (si vous voulez une frontière) et de faire rec.Width = (int)((rec.Width * scaleFactor) - 4)enrec.Width = (int)(rec.Width * scaleFactor) + 1
Midri
14

Modification de la réponse de dustyburwell. (Je n'ai pas assez de représentants pour le modifier moi-même.) Comme sa réponse, cela fonctionne avec les "Styles visuels" activés. Vous pouvez simplement définir la propriété ForeColor de la barre de progression dans la vue de conception du formulaire.

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);
    }
}
Matt Blaine
la source
Cela fonctionne très bien pour changer la couleur de premier plan, mais cela scintille beaucoup, contrairement au contrôle ProgressBar par défaut. Aucune idée sur la façon de résoudre ça?
Ravitaillé
4
J'ai découvert comment résoudre le scintillement: ajoutez un double tampon aux ControlStyles de la ProgressBar définie par l'utilisateur, comme ceci: SetStyle (ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer, ...).
Ravitaillé
Je me rends compte que c'est vieux; et je me rends compte que c'est un nit (parce que le minimum est presque toujours zéro); mais le facteur d'échelle de largeur doit être (((double) Valeur - (double) Minimum) / ((double) Maximum - (double) Minimum)) pour être anal-rétentivement correct. :)
Jesse Chisholm
5

Je viens de mettre cela dans une classe statique.

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

J'espère que ça aide,

Marc

Marc
la source
+1: Je pense que c'est ce que la plupart des gens entendaient par rouge. Faire afficher un état d'erreur.
quantum
3

Habituellement, la barre de progression a un thème ou respecte les préférences de couleur de l'utilisateur. Donc, pour changer la couleur, vous devez soit désactiver les styles visuels et définir ForeColorou dessiner le contrôle vous-même.

En ce qui concerne le style continu au lieu de blocs, vous pouvez définir la Stylepropriété:

pBar.Style = ProgressBarStyle.Continuous;
Joey
la source
2

ÉDITER

Par le son des choses, vous utilisez le thème XP qui a la barre de programme basée sur le bloc vert. Essayez de basculer votre style d'interface utilisateur vers Windows Classic et testez à nouveau, mais vous devrez peut-être implémenter votre propre événement OnPaint pour qu'il fasse ce que vous voulez dans tous les styles d'interface utilisateur

Ou comme quelqu'un d'autre l'a souligné, désactivez les VisualStyles pour votre application.

Original

Autant que je sache, le rendu de la barre de progression se fait en ligne avec le style de thème Windows que vous avez choisi (win2K, xp, vista)

Vous pouvez changer la couleur en définissant la propriété

ProgressBar.ForeColor

Je ne suis pas sûr que vous puissiez faire beaucoup plus cependant ...

fait quelques recherches sur Google

Theres un article ici de MS KB sur la création d'une barre de progression "lisse"

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

Eoin Campbell
la source
@ Eion, Forecolor = rouge; Backcolor = bleu; Style = continu. Rien n'a changé, c'est comme si je ne l'ai jamais touché.
Ivan Prodanov le
2

Toutes ces méthodes ne fonctionnent pas pour moi, mais cette méthode vous permet de la changer en une chaîne de couleur.

Veuillez noter que j'ai trouvé ce code ailleurs sur StackOverflow et que je l'ai un peu changé. Depuis, j'ai oublié où j'ai trouvé ce code et je ne peux pas le lier à cause de cela, désolé pour cela.

Mais de toute façon j'espère que ce code aide quelqu'un, il m'a vraiment aidé.

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

Lorsque le nom "ProgressBar" est utilisé, remplacez-le par votre propre nom de barre de progression. Vous pouvez également déclencher cet événement avec d'autres arguments, assurez-vous simplement qu'il est entre crochets quelque part.

EpicNinjaFromage
la source
beau travail..J'utilise un événement ProgressChanged pour passer du clair au sombre ... + 1
BENN1TH
2

Changement Coloret Value(changement instantané)

Mettre using System.Runtime.InteropServices;en haut ...

Appeler avec ColorBar.SetState(progressBar1, ColorBar.Color.Yellow, myValue);

J'ai remarqué que si vous modifiez la valeur de la barre (sa taille), elle ne changera pas si elle est dans une couleur autre que le vert par défaut. J'ai pris le code de user1032613 et ajouté une option 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
    }

}
Sparfy
la source
2
Nous avons dû retourner pBar.Value = pBar.Maximum;et à l' SendMessage(pBar.Handle, 1040, (IntPtr)(int)Color.Green, IntPtr.Zero);intérieur du corps de la condition pour que la progression montre la nouvelle couleur correcte.
DomTheDeveloper
1

Juste au cas où quelqu'un chercherait une autre option ... vous pouvez étendre un panneau, l'utiliser comme arrière-plan (blanc ou autre), ajouter un autre panneau à l'intérieur pour le premier plan (la barre mobile). Ensuite, vous avez un contrôle total sur le changement de couleur, etc.

Eduardo
la source
1

Cliquez simplement avec le bouton droit sur votre projet dans l'Explorateur de solutions Visual Basic (où se trouvent vos fichiers vb) et sélectionnez les propriétés dans le menu. Dans la fenêtre qui apparaît, désélectionnez "Activer les styles visuels XP" et maintenant, lorsque vous définissez la couleur, cela devrait fonctionner maintenant.

Excité
la source
0

Tous: Quote: Habituellement, la barre de progression est soit thématique, soit respecte les préférences de couleur de l'utilisateur. Donc, pour changer la couleur, vous devez soit désactiver les styles visuels et définir ForeColorou dessiner le contrôle vous-même.

En ce qui concerne le style continu au lieu de blocs, vous pouvez définir la Stylepropriété:

pBar.Style = ProgressBarStyle.Continuous;

ProgressBarStyle.Continuous versus Blocks est inutile avec VistualStyles activé ...

Les blocs ne fonctionneront qu'avec les styles visuels désactivés ... ce qui rend tout cela un point discutable (en ce qui concerne la couleur de progression personnalisée) Avec les styles virtuels désactivés ... la barre de progression doit être colorée en fonction de la couleur avant.

J'ai utilisé une combinaison de la réponse de William Daniel (avec les styles visuels activés, donc le ForeColor ne sera pas simplement plat sans style) et la réponse de Barry (au texte personnalisé sur la barre de progression) de: Comment mettre du texte sur ProgressBar?

NeoH4x0r
la source
0

Barre verticale UP For Down de couleur rouge:

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

    } 
}
Mandrova
la source
Pouvez-vous s'il vous plaît expliquer dans le texte ou dans les commentaires du code comment cela résout le problème.
Harrison
Je me rends compte que c'est une nit (parce que le minimum est presque toujours zéro); mais le facteur d'échelle de hauteur doit être (((double) Valeur - (double) Minimum) / ((double) Maximum - (double) Minimum)) pour être anal-rétentivement correct. :)
Jesse Chisholm
0

La barre de progression colorée VB.Net qui respecte la réponse des styles visuels WXP est ...

J'ai commencé avec la réponse de 'user1032613' le 17/03/12. Notez que c'est maintenant un module, pas une classe. À partir de là, j'ai converti le code, mais il en fallait plus. En particulier, le code converti montrait une fonction DirectCast pour convertir l'entier «state» en un type IntPtr qui ne fonctionnait pas.

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

Et encore une fois, appelez simplement ceci dans le code d'utilisation avec cette ligne:

Call ModifyProgressBarColor.SetState(prb, 2)

BTW - J'ai essayé d'autres couleurs - 0, 4, 5 - elles affichent toutes simplement du vert.

DanW52
la source
0

Je sais que c'est trop vieux pour qu'on y réponde maintenant ... mais quand même, un petit ajustement à @ la réponse Daniel pour corriger le problème de ne pas afficher la barre de progression à valeur nulle. Dessinez simplement la progression uniquement si la largeur du rectangle intérieur est non nulle.

Merci à tous les contributeurs.

        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();
                        }
                    }
                }
            }
        }
Les divins Mathew
la source
0

J'ai trouvé que cela pouvait être fait en dessinant un rectangle à l'intérieur de la barre de progression et en définissant sa largeur en fonction de la valeur actuelle de la progression. J'ai également ajouté un support pour les progrès de droite à gauche. De cette façon, vous n'avez pas besoin d'utiliser l'image, et comme Rectnalge.Inflate n'est pas appelé, le rectangle dessiné est plus petit.

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);
        }
    }
}
ZOK
la source
0

Je pense que les solutions les plus simples de toutes, ce n'est qu'une solution rapide, mais vous pouvez supprimer, commenter Application.EnableVisualStyles () de Program.cs, ou comment vous avez nommé la partie contenant la fonction Main. Après cela, vous pouvez librement changer la couleur de la barre de progression par progressBar.ForeColor = Color.TheColorYouDesire;

static void Main()
        {
            //Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
         }
Mladen Tasevski
la source
-5

Edit: dans les deux minuites, il m'a fallu lancer vs et vérifier la syntaxe que j'ai été battue avec de bien meilleures réponses. j'adore ce site.

        progressBar1 = new ProgressBar();
        progressBar1.ForeColor = Color.Red;
Fusspawn
la source
2
Ne fonctionne pas.Il reste vide maintenant, j'ai ajouté progressBar1.value = 50, mais toujours vide
Ivan Prodanov
essayé de définir la valeur maxiumum? progressBar1 = nouveau ProgressBar (); progressBar1.ForeColor = Color.Red; progressBar1.Maximum = 100;
Fusspawn
2
Non, le problème est dans mon thème Windows.
Ivan Prodanov le
Aucune idée si cela fonctionnera, mais essayez de commenter Application.EnableVisualThemes (); qui est dans l'un des fichiers prédéfinis vs generate (je ne me souviens pas de celui-là)
Fusspawn
1
Application.EnableVisualStyles () désolé pas les thèmes
Fusspawn