Pagina personale di:
Carlo Vecchio
appunti di C#, R, SQL Server, ASP.NET, algoritmi, numeri
Vai ai contenuti

C# - Controlli Utente (ProgressBar)

C#
Progetto di una ProgressBar
Introduzione
  • La ProgressBar fornita con l'IDE di VisualStudio presenta alcuni limiti:
    • Colori non configurabili (né dello sfondo, né della barra).
    • Valore percentuale non presente.
    • Ha un effetto di 'movimento' che può risultare fastidioso.
  • L'obiettivo è quello di progettare una ProgressBar con le seguenti caratteristiche:
    • Colore di sfondo configurabile.
    • Colore della barra configurabile.
    • Valore percentuale abilitabile o no, con font a scelta del progettista.
    • Evento al cambio del valore percentuale.
  • Il risultato che si vuole ottenere è il seguente:



  • Come si vede, le quattro ProgressBar disegnate hanno le caratteristiche sopra richieste.
  • Nella seconda sono stati cambiati i colori, nella terza è stato modificato il font, nella quarta è stato tolto il font e ristretto il controllo.

Creazione della ProgressBar
  • Per crere la ProgressBar bisogna seguire i passi indicati nella pagina Controlli Utente (User Control).
  • Riassumendo:
    • Il primo progetto è una applicazione Windows Form, con un Form (che serve da sviluppo e test del controllo) e il controllo vero e proprio (che consiste di una parte visuale e di una parte di codice).
    • Il secondo progetto è una applicazione Windows Library, che riceve il controllo e produce una DLL.
  • Ci si focalizza ora sul primo progetto, quello dove c'è la logica della ProgressBar.
  • Il Design del controllo è molto semplice:



  • È costituito da due oggetti Panel, quello esterno è chiamato 'pnlContainer', quello interno è chiamato 'pnlProgressBar'.
  • Il codice è invece il seguente:

   public partial class CV_ProgressBar : UserControl
   {
       // Variabili interne.
       private int _Value = 0;
       private bool _ShowPercentage = true;
       private Color _BackColorBar = Color.Blue;
       private Color _ForeColorFont = Color.Black;
       private Font _FontOfPercentage = new Font("Verdana", 9);

       // Eventi.
       public event EventHandler ValueChanged;

       public CV_ProgressBar()
       {
           InitializeComponent();
       }

       private void CV_ProgressBar_Load(object sender, EventArgs e)
       {
           // Imposta il pnlContainer.
           pnlContainer.Dock = DockStyle.Fill;
           pnlContainer.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
           // Imposta il pnlProgressBar.
           pnlProgressBar.Parent = pnlContainer;   // Contenuto nel pnlContainer.
           pnlProgressBar.Top = 0;
           pnlProgressBar.Left = 0;
           pnlProgressBar.Height = pnlContainer.Height;
           pnlProgressBar.Width = pnlContainer.Width * _Value / 100;
           pnlProgressBar.BorderStyle = System.Windows.Forms.BorderStyle.None;
           pnlProgressBar.BringToFront();
       }

       #region Proprietà.
       // Valore della ProgressBar.
       public int Value
       {
           get { return _Value; }
           set
           {
               try
               {
                   if (value < 0)
                       value = 0;
                   if (value > 100)
                       value = 100;
                   if (_Value == value)
                       return;
                   // Si imposta la variabile interna.
                   _Value = value;
                   // Si disegna il pnlProgressBar con larghezza opportuna.
                   pnlProgressBar.Width = pnlContainer.Width * value / 100;
                   // Si forzano gli eventi Paint() dei Panel.
                   pnlContainer.Refresh();
                   pnlProgressBar.Refresh();
                   // Genera l'evento.
                   EventHandler handler = ValueChanged;
                   if (handler != null)
                       handler(this, EventArgs.Empty);
               }
               catch (Exception)
               {
               }
           }
       }
       // Bool per mostrare o no la stringa con la percentuale.
       public bool ShowPercentage
       {
           get { return _ShowPercentage; }
           set { _ShowPercentage = value; }
       }

       // BackColor del pannello interno.
       public Color BackColorBar
       {
           get { return _BackColorBar; }
           set
           {
               _BackColorBar = value;
               pnlProgressBar.BackColor = _BackColorBar;
           }
       }

       // Font del valore percentuale.
       public Font FontOfPercentage
       {
           get { return _FontOfPercentage; }
           set { _FontOfPercentage = value; }
       }

       // ForeColor del valore percentuale.
       public Color ForeColorFont
       {
           get { return _ForeColorFont; }
           set { _ForeColorFont = value; }
       }
       #endregion

       private void pnl_Paint(object sender, PaintEventArgs e)
       {
           if (!_ShowPercentage)
           {
               return;
           }
           try
           {
               // Crea la stringa.
               String drawString = _Value.ToString() + "%";

               // Crea font e brush.
               Font drawFont = _FontOfPercentage;
               SolidBrush drawBrush = new SolidBrush(_ForeColorFont);
 
               // Dimensione della stringa da mostrare.
               SizeF sizeString = new SizeF();
               using (Graphics g = Graphics.FromImage(new Bitmap(1, 1)))
               {
                   sizeString = g.MeasureString(drawString, drawFont);
               }

               // Crea il punto nell'angolo alto a sinistra.
               float left = (pnlContainer.Width - sizeString.Width) / 2;
               float top = (pnlContainer.Height - sizeString.Height) / 2;
               PointF drawPoint = new PointF(left, top);

               // Disegna la stringa.
               e.Graphics.DrawString(drawString, drawFont, drawBrush, drawPoint);
           }
           catch (Exception)
           {
           }
       }
   }

  • Alcuni commenti sul codice sopra esposto.
  • Sono definite le variabili interne, una per ogni proprietà pubblica del controllo.
  • È definito un 'EventHandler', che serve per gestire l'evento 'ValueChanged'.
  • È poi presente il costruttore della classe.
  • Nell'evento Load(), sono impostati alcuno aspetti estetici dei due pannelli che costituiscono il controllo.
  • Nella proprietà 'Value' ci sono alcune cose interessanti:
    • Viene controllato il valore passato.
    • Viene ridisegnata la larghezza del pannello 'pnlProgressBar'.
    • Sono poi forzati gli eventi 'Paint()' del pannelli.
    • Viene infine generato l'evento 'ValueChanged()'.
  • Sono poi definite le proprietà 'ShowPercentage', 'BackColorBar', 'FontOfPercentage' e 'ForeColorFont'.
  • Viene definito l'evento Paint(), esso è chiamato da entrambe i pannelli. Anche in questo evento ci sono degli aspetti interessanti.
    • Viene creato un oggetto 'SolidBrush': esso serve per scrivere la stringa con il valore percentuale.
    • Si è preferito utilizzare questo oggetto perché l'utilizzo di una semplice Label non avrebbe dato dei risultati estetici corretti. Infatti l'oggetto Label presenta un colore di sfondo che non è possibile rendere trasparente.
    • Una considerazione va anche posta al fatto che il valore della percentuale è scritto in entrambe i pannelli, in modo da gestire la parziale sovrapposizione del primo pannello con il secondo.

Riassunto Proprietà / Eventi
  • Value: int, imposta il valore percentuale della ProgressBar, da 0 a 100.
  • ShowPercentage: boolean, 'true' mostra una stringa sulla ProgressBar con il valore percentuale.
  • BackColor: Color, imposta il colore dello sfondo della ProgressBar.
  • BackColorBar: Color, imposta il colore della barra colorata.
  • FontPercentage: Font, è il font utilizzato per disegnare il valore percentuale.
  • FontColor: Color, è il colore del font del valore percentuale.
  • Evento ValueChanged(): generato quando cambia la proprietà 'Value'.

Sorgenti e DLL


© 2022 Carlo Vecchio
Torna ai contenuti