52 votes

Comment mettre du texte sur la ProgressBar ?

J'ai utilisé le contrôle ProgressBar dans mon application de bureau C#. Je l'ai utilisé dans un thread autre que celui dans lequel le contrôle a été déclaré. Maintenant, je me demande comment je peux afficher un texte à l'intérieur de la barre de progression comme "Initiating Registration" etc. Je veux aussi l'utiliser comme une barre de progression Marquee.

3 votes

Cela dépend, utilisez-vous WinForms ou WPF ?

9 votes

C'est de loin la solution la plus simple : dreamincode.net/forums/topic/

1 votes

Voici un bon tutoriel codeproject.com/Articles/31406/

72voto

Barry Points 18913

Vous devrez surcharger la méthode OnPaint, appeler l'implémentation de base et peindre votre propre texte.

Vous devrez créer votre propre CustomProgressBar et ensuite remplacer OnPaint pour dessiner le texte que vous voulez.

Classe de barre de progression personnalisée

namespace ProgressBarSample
{

public enum ProgressBarDisplayText
{
    Percentage,
    CustomText
}

class CustomProgressBar: ProgressBar
{
    //Property to set to decide whether to print a % or Text
    public ProgressBarDisplayText DisplayStyle { get; set; }

    //Property to hold the custom text
    public String CustomText { get; set; }

    public CustomProgressBar()
    {
        // Modify the ControlStyles flags
        //http://msdn.microsoft.com/en-us/library/system.windows.forms.controlstyles.aspx
        SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        Rectangle rect = ClientRectangle;
        Graphics g = e.Graphics;

        ProgressBarRenderer.DrawHorizontalBar(g, rect);
        rect.Inflate(-3, -3);
        if (Value > 0)
        {
            // As we doing this ourselves we need to draw the chunks on the progress bar
            Rectangle clip = new Rectangle(rect.X, rect.Y, (int)Math.Round(((float)Value / Maximum) * rect.Width), rect.Height);
            ProgressBarRenderer.DrawHorizontalChunks(g, clip);
        }

        // Set the Display text (Either a % amount or our custom text
        int percent = (int)(((double)this.Value / (double)this.Maximum) * 100); 
        string text = DisplayStyle == ProgressBarDisplayText.Percentage ? percent.ToString() + '%' : CustomText;            

        using (Font f = new Font(FontFamily.GenericSerif, 10))
        {

            SizeF len = g.MeasureString(text, f);
            // Calculate the location of the text (the middle of progress bar)
            // Point location = new Point(Convert.ToInt32((rect.Width / 2) - (len.Width / 2)), Convert.ToInt32((rect.Height / 2) - (len.Height / 2)));
            Point location = new Point(Convert.ToInt32((Width / 2) - len.Width / 2), Convert.ToInt32((Height / 2) - len.Height / 2)); 
            // The commented-out code will centre the text into the highlighted area only. This will centre the text regardless of the highlighted area.
            // Draw the custom text
            g.DrawString(text, f, Brushes.Red, location);
        }
    }
}
}

Exemple d'application WinForms

using System;
using System.Linq;
using System.Windows.Forms;
using System.Collections.Generic;

namespace ProgressBarSample
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            // Set our custom Style (% or text)
            customProgressBar1.DisplayStyle = ProgressBarDisplayText.CustomText;
            customProgressBar1.CustomText = "Initialising";
        }

        private void btnReset_Click(object sender, EventArgs e)
        {
            customProgressBar1.Value = 0;
            btnStart.Enabled = true;
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            btnReset.Enabled = false;
            btnStart.Enabled = false;

            for (int i = 0; i < 101; i++)
            {

                customProgressBar1.Value = i;
                // Demo purposes only
                System.Threading.Thread.Sleep(100);

                // Set the custom text at different intervals for demo purposes
                if (i > 30 && i < 50)
                {
                    customProgressBar1.CustomText = "Registering Account";
                }

                if (i > 80)
                {
                    customProgressBar1.CustomText = "Processing almost complete!";
                }

                if (i >= 99)
                {
                    customProgressBar1.CustomText = "Complete";
                }
            }

            btnReset.Enabled = true;

        }

    }
}

0 votes

Des exemples de fonctionnement ? Je n'arrive jamais à faire apparaître ce que j'ajoute à OnPaint.

2 votes

@MatthewLock : J'ai ajouté le code pour la classe de barre de progression personnalisée et l'application type. J'espère que cela vous aidera

0 votes

Veuillez ajouter "this.Controls.Add(customProgressBar1) ;" au constructeur de Main1().

32voto

Andrew Points 2027

J'ai écrit un pas de clignotement/clignotement TextProgressBar

Vous pouvez trouver le code source ici : https://github.com/ukushu/TextProgressBar

enter image description here

AVERTISSEMENT : C'est un peu bogué ! Mais quand même, je pense que c'est mieux que d'autres réponses ici. Comme je n'ai pas le temps de faire des corrections, si vous voulez faire quelque chose avec eux, s'il vous plaît envoyez-moi la mise à jour par un moyen quelconque :) Merci.

Des échantillons :

enter image description here enter image description here no blinking/flickering TextProgressBar

no blinking/flickering TextProgressBar enter image description here enter image description here

16voto

rdongart Points 61

ÉVITER LE SCINTILLEMENT DU TEXTE

El solution fournie par Barry ci-dessus est excellente, mais il y a le "flicker-problem".

Dès que la valeur est supérieure à zéro, la fonction OnPaint sera invoquée à plusieurs reprises et le texte clignotera.

Il existe une solution à ce problème. Nous n'avons pas besoin de VisualStyles pour l'objet puisque nous allons le dessiner avec notre propre code.

Ajoutez le code suivant à l'objet personnalisé que Barry a écrit et vous éviterez le scintillement :

    [DllImportAttribute("uxtheme.dll")]
    private static extern int SetWindowTheme(IntPtr hWnd, string appname, string idlist);

    protected override void OnHandleCreated(EventArgs e)
    {
        SetWindowTheme(this.Handle, "", "");
        base.OnHandleCreated(e);
    }

Je ne l'ai pas écrit moi-même. Je l'ai trouvé ici : https://stackoverflow.com/a/299983/1163954

Je l'ai testé et il fonctionne.

11voto

Je créerais un contrôle nommé par exemple InfoProgresBar, qui fournirait cette fonctionnalité avec une ou deux étiquettes (Main Job, Current Job) et une barre de progression et je l'utiliserais à la place de cette barre de progression.

0 votes

La barre de progression personnalisée semble être une bonne idée, je vais l'essayer... Merci.

8voto

pooria haddad Points 420

J'ai utilisé ce code simple, et ça marche !

for (int i = 0; i < N * N; i++)
     {
        Thread.Sleep(50);
        progressBar1.BeginInvoke(new Action(() => progressBar1.Value = i));
        progressBar1.CreateGraphics().DrawString(i.ToString() + "%", new Font("Arial",
        (float)10.25, FontStyle.Bold),
        Brushes.Red, new PointF(progressBar1.Width / 2 - 10, progressBar1.Height / 2 - 7));
     }

Il n'a qu'un seul problème et c'est celui-ci : lorsque la barre de progression commence à monter, le pourcentage se cache parfois, puis réapparaît. Je ne l'ai pas écrit moi-même, je l'ai trouvé ici : texte sur la barre de progression en c#

J'ai utilisé ce code, et il fonctionne.

2 votes

C'est mauvais parce que cela entraîne une fuite de l'objet Graphics, et ne se redessinera pas après avoir été obscurci.

0 votes

Techniquement, il n'y a pas de "fuite" en soi, car tout est géré ; le nombre de références de l'objet Graphique atteindra zéro immédiatement après cette ligne, ce qui permet de collecter les déchets. Je suis d'accord que cela pourrait être mieux géré, cependant.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X