Condividi tramite


Esempio di controllo Windows Form

In questo esempio viene descritto un controllo personalizzato (FlashTrackBar) che può essere utilizzato per visualizzare il livello o lo stato di avanzamento di un'applicazione. Tale controllo utilizza una sfumatura per rappresentare visivamente l'avanzamento. Per scaricare il codice sorgente per FlashTrackBar e visualizzare un esempio di come viene utilizzato, vedere l'esempio CustomUITypeEditor in Esempi di .NET – Windows Form: Creazione di controlli. Nell'argomento vengono descritti gli editor utilizzati nell'esempio del controllo FlashTrackBar sottostante.

Nel controllo FlashTrackBar vengono descritti i concetti seguenti:

  • Definizione di proprietà personalizzate.
  • Definizione di eventi personalizzati. FlashTrackBar definisce l'evento ValueChanged.
  • Esecuzione dell'override del metodo OnPaint per fornire la logica necessaria per la progettazione del controllo.
  • Calcolo dell'area disponibile per la progettazione del controllo tramite la proprietà ClientRectangle. Il controllo FlashTrackBar esegue tale operazione nel metodo OptimizedInvalidate.
  • Implementazione della serializzazione (persistenza) per una proprietà al momento della modifica nella finestra di progettazione. Il controllo FlashTrackBar definisce i metodi ShouldSerializeStartColor e ShouldSerializeEndColor per la serializzazione delle proprietà StartColor e EndColor.

Il controllo FlashTrackBar definisce le proprietà personalizzate seguenti:

  • AllowUserEdit

    Indica se l'utente può modificare il valore del controllo FlashTrackBar selezionandolo e trascinandolo.

  • EndColor

    Specifica il colore finale della barra di avanzamento.

  • DarkenBy

    Specifica di quanto scurire lo sfondo rispetto alla sfumatura in primo piano.

  • Max

    Specifica il valore massimo della barra di avanzamento.

  • Min

    Specifica il valore minimo della barra di avanzamento.

  • StartColor

    Specifica il colore iniziale della sfumatura.

  • ShowPercentage

    Indica se visualizzare una percentuale sulla sfumatura.

  • ShowValue

    Indica se visualizzare il valore corrente sulla sfumatura.

  • ShowGradient

    Indica se sulla barra di avanzamento deve essere visualizzata una sfumatura di colore che indica il valore corrente.

  • Value

    Specifica il valore corrente della barra di avanzamento.

Il controllo FlashTrackBar definisce l'evento proprietà modificata seguente e il metodo che genera tale evento:

  • ValueChanged

    L'evento che viene generato quando la proprietà Value della barra di avanzamento viene modificata.

  • OnValueChanged

    Il metodo che genera l'evento ValueChanged.

    Nota   Il controllo FlashTrackBar utilizza la classe EventArgs per i dati dell'evento e la classe EventHandler per il delegato dell'evento.

Per gestire gli eventi NomeEvento corrispondenti, il controllo FlashTrackBar esegue l'override dei metodi seguenti ereditati da System.Windows.Forms.Control:

Per gestire gli eventi proprietà modificata corrispondenti, il controllo FlashTrackBar esegue l'override dei metodi seguenti ereditati da System.Windows.Forms.Control:

Imports System
Imports System.ComponentModel
Imports System.ComponentModel.Design
Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.Drawing.Design
Imports System.Windows.Forms
Imports System.Diagnostics

Namespace Microsoft.Samples.WinForms.VB.FlashTrackBar

    Public Class FlashTrackBar
        Inherits System.Windows.Forms.Control

        Private LeftRightBorder As Integer = 10
        Private myValue As Integer = 0
        Private myMin As Integer = 0
        Private myMax As Integer = 100
        Private myShowPercentage As Boolean = False
        Private myShowValue As Boolean = False
        Private myAllowUserEdit As Boolean = True
        Private myShowGradient As Boolean = True
        Private dragValue As Integer = 0
        Private dragging As Boolean = False
        Private myStartColor As Color = Color.Red
        Private myEndColor As Color = Color.LimeGreen
        Private baseBackground As Brush
        Private backgroundDim As Brush
        Private myDarkenBy As Byte = 200

        Public Sub New()

            MyBase.New()

            ' This call is required by the Windows Forms Designer.
            InitializeComponent()

            ' Add any initialization after the InitializeComponent() call.
            SetStyle(ControlStyles.Opaque, True)
            SetStyle(ControlStyles.ResizeRedraw, True)
            Debug.Assert(GetStyle(ControlStyles.ResizeRedraw), "Should be redraw!")
        End Sub

        ' Form overrides Dispose to clean up the component list.
       Protected  Overloads Overrides Sub Dispose(disposing As Boolean)
        If disposing
         If Not components Is Nothing
            components.Dispose()
         End If
        End If
         MyBase.Dispose(disposing)
      End Sub

#Region " Windows Forms Designer generated code "

        ' Required by the Windows Forms Designer.
        Private components As System.ComponentModel.Container

        ' Note: The following procedure is required by the Windows Forms Designer.
        ' It can be modified using the Windows Forms Designer.
        ' Do not modify it using the code editor.
        Private Sub InitializeComponent()
            Me.components = New System.ComponentModel.Container()
            Me.ForeColor = System.Drawing.Color.White
            Me.BackColor = System.Drawing.Color.Black
            Me.Size = New System.Drawing.Size(100, 23)
            Me.Text = "FlashTrackBar"
        End Sub

#End Region


        <Category("Flash"), DefaultValue(True)> Public Property AllowUserEdit() As Boolean
            Get
                Return myAllowUserEdit
            End Get

            Set(ByVal Value As Boolean)
                If (Value <> myAllowUserEdit) Then
                    myAllowUserEdit = Value
                    If Not (myAllowUserEdit) Then
                        Capture = False
                        dragging = False
                    End If
                End If
            End Set

        End Property


        <Category("Flash")> Public Property EndColor() As Color
            Get
                Return myEndColor
            End Get

            Set(ByVal Value As Color)
                myEndColor = Value
                If (Not (baseBackground Is Nothing) And myShowGradient) Then
                    baseBackground.Dispose()
                    baseBackground = Nothing
                End If
                Invalidate()
            End Set
        End Property


        Public Function ShouldSerializeEndColor() As Boolean
            Return Not (myEndColor.Equals(Color.LimeGreen))
        End Function


        <Category("Flash"), _
            Editor(GetType(FlashTrackBarDarkenByEditor), GetType(UITypeEditor)), _
            DefaultValue(200)> _
        Public Property DarkenBy() As Byte
            Get
                Return myDarkenBy
            End Get
            Set(ByVal Value As Byte)
                If (Value <> myDarkenBy) Then
                    myDarkenBy = Value
                    If Not (backgroundDim Is Nothing) Then
                        backgroundDim.Dispose()
                        backgroundDim = Nothing
                    End If
                    OptimizedInvalidate(Value, Max)
                End If
            End Set
        End Property

        <Category("Flash"), DefaultValue(100)> _
        Public Property Max() As Integer
            Get
                Return myMax
            End Get
            Set(ByVal Value As Integer)
                If (myMax <> Value) Then
                    myMax = Value
                    Invalidate()
                End If
            End Set
        End Property


        <Category("Flash"), DefaultValue(0)> _
        Public Property Min() As Integer
            Get
                Return myMin
            End Get
            Set(ByVal Value As Integer)
                If (Min <> Value) Then
                    Min = Value
                    Invalidate()
                End If
            End Set
        End Property


        <Category("Flash")> Public Property StartColor() As Color
            Get
                Return myStartColor
            End Get
            Set(ByVal Value As Color)
                myStartColor = Value
                If (Not (baseBackground Is Nothing) And myShowGradient) Then
                    baseBackground.Dispose()
                    baseBackground = Nothing
                End If
                Invalidate()
            End Set
        End Property

        Public Function ShouldSerializeStartColor() As Boolean
            Return Not (StartColor.Equals(Color.Red))
        End Function


        <Category("Flash"), _
            RefreshProperties(RefreshProperties.Repaint), _
            DefaultValue(False)> _
        Public Property ShowPercentage() As Boolean
            Get
                Return myShowPercentage
            End Get
            Set(ByVal Value As Boolean)
                If (Value <> myShowPercentage) Then
                    myShowPercentage = Value
                    If (myShowPercentage) Then
                        myShowValue = False
                    End If
                    Invalidate()
                End If
            End Set
        End Property


        <Category("Flash"), _
            RefreshProperties(RefreshProperties.Repaint), _
            DefaultValue(False)> _
        Public Property ShowValue() As Boolean
            Get
                Return myShowValue
            End Get
            Set(ByVal Value As Boolean)
                If (Value <> myShowValue) Then
                    myShowValue = Value
                    If (myShowValue) Then
                        myShowPercentage = False
                    End If
                    Invalidate()
                End If
            End Set
        End Property



        <Category("Flash"), DefaultValue(True)> _
        Public Property ShowGradient() As Boolean
            Get
                Return myShowGradient
            End Get
            Set(ByVal Value As Boolean)
                If (Value <> myShowGradient) Then
                    myShowGradient = Value
                    If Not (baseBackground Is Nothing) Then
                        baseBackground.Dispose()
                        baseBackground = Nothing
                    End If
                    Invalidate()
                End If
            End Set
        End Property

        <Category("Flash"), _
         Editor(GetType(FlashTrackBarValueEditor), GetType(UITypeEditor)), _
         DefaultValue(0)> _
        Public Property Value() As Integer
            Get
                If (dragging) Then
                    Return dragValue
                End If
                Return myValue
            End Get
            Set(ByVal Value As Integer)
                If (Value <> myValue) Then
                    Dim old As Integer = myValue
                    myValue = Value
                    OnValueChanged(EventArgs.Empty)
                    OptimizedInvalidate(old, myValue)
                End If
            End Set
        End Property

        ' ValueChanged event.

        <Description("Raised when the Value displayed changes")> _
        Public Event ValueChanged(ByVal sender As Object, ByVal ev As EventArgs) 
        ' As EventHandler.


        Private Sub OptimizedInvalidate(ByVal oldValue As Integer, ByVal newValue As Integer)
            Dim client As Rectangle = ClientRectangle

            Dim oldPercentValue As Single = CSng(oldValue) / (CSng(Max) - CSng(Min))
            Dim oldNonDimLength As Integer = CInt(oldPercentValue * CSng(client.Width))

            Dim newPercentValue As Single = (CSng(newValue) / (CSng(Max) - CSng(Min)))
            Dim newNonDimLength As Integer = CInt(newPercentValue * CSng(client.Width))

            Dim lmin As Integer = Math.Min(oldNonDimLength, newNonDimLength)
            Dim lmax As Integer = Math.Max(oldNonDimLength, newNonDimLength)

            Dim invalid As Rectangle = New Rectangle(client.X + lmin, client.Y, lmax - lmin, client.Height)
            Invalidate(invalid)

            Dim oldToDisplay As String
            Dim newToDisplay As String

            If (ShowPercentage) Then
                oldToDisplay = Convert.ToString(CInt(oldPercentValue * 100F)) + "%"
                newToDisplay = Convert.ToString(CInt(newPercentValue * 100F)) + "%"
            ElseIf (ShowValue) Then
                oldToDisplay = Convert.ToString(oldValue)
                newToDisplay = Convert.ToString(newValue)
            Else
                oldToDisplay = Nothing
                newToDisplay = Nothing
            End If

            If (oldToDisplay <> Nothing And newToDisplay <> Nothing) Then
                Dim g As Graphics = CreateGraphics()
                Dim oldFontSize As SizeF = g.MeasureString(oldToDisplay, Font)
                Dim newFontSize As SizeF = g.MeasureString(newToDisplay, Font)
                Dim oldFontRectF As RectangleF = New RectangleF(New PointF(0, 0), oldFontSize)
                Dim newFontRectF As RectangleF = New RectangleF(New PointF(0, 0), newFontSize)
                oldFontRectF.X = (client.Width - oldFontRectF.Width) / 2
                oldFontRectF.Y = (client.Height - oldFontRectF.Height) / 2
                newFontRectF.X = (client.Width - newFontRectF.Width) / 2
                newFontRectF.Y = (client.Height - newFontRectF.Height) / 2

                Dim oldFontRect As Rectangle = New Rectangle(CInt(oldFontRectF.X), CInt(oldFontRectF.Y), CInt(oldFontRectF.Width), CInt(oldFontRectF.Height))
                Dim newFontRect As Rectangle = New Rectangle(CInt(newFontRectF.X), CInt(newFontRectF.Y), CInt(newFontRectF.Width), CInt(newFontRectF.Height))

                Invalidate(oldFontRect)
                Invalidate(newFontRect)
            End If
        End Sub



        Protected Overrides Sub OnMouseDown(ByVal e As MouseEventArgs)
            MyBase.OnMouseDown(e)
            If Not (myAllowUserEdit) Then
                Return
            End If
            Capture = True
            dragging = True
            SetDragValue(New Point(e.X, e.Y))
        End Sub

        Protected Overrides Sub OnMouseMove(ByVal e As MouseEventArgs)
            MyBase.OnMouseMove(e)
            If (Not myAllowUserEdit Or Not dragging) Then
                Return
            End If
            SetDragValue(New Point(e.X, e.Y))
        End Sub

        Protected Overrides Sub OnMouseUp(ByVal e As MouseEventArgs)
            MyBase.OnMouseUp(e)
            If (Not myAllowUserEdit Or Not dragging) Then
                Return
            End If
            Capture = False
            dragging = False
            Value = dragValue
            OnValueChanged(EventArgs.Empty)
        End Sub

        Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
            MyBase.OnPaint(e)

            If (baseBackground Is Nothing) Then

                If (myShowGradient) Then
                    baseBackground = New LinearGradientBrush(New Point(0, 0), _
                                                             New Point(ClientSize.Width, 0), _
                                                             StartColor, _
                                                             EndColor)
                ElseIf Not (BackgroundImage Is Nothing) Then
                    baseBackground = New TextureBrush(BackgroundImage)
                Else
                    baseBackground = New SolidBrush(BackColor)
                End If

            End If

            If (backgroundDim Is Nothing) Then
                backgroundDim = New SolidBrush(Color.FromArgb(DarkenBy, Color.Black))
            End If

            Dim toDim As Rectangle = ClientRectangle
            Dim percentValue As Single = (CSng(Value) / (CSng(Max) - CSng(Min)))
            Dim nonDimLength As Integer = CInt(percentValue * CSng(toDim.Width))
            toDim.X = toDim.X + nonDimLength
            toDim.Width = toDim.Width - nonDimLength

            Dim ltext As String = Me.Text
            Dim toDisplay As String
            Dim textRect As RectangleF = New RectangleF(0, 0, 0, 0)

            If (ShowPercentage Or ShowValue Or ltext.Length > 0) Then

                If (ShowPercentage) Then
                    toDisplay = Convert.ToString(CInt(percentValue * 100F)) + "%"
                ElseIf (ShowValue) Then
                    toDisplay = Convert.ToString(Value)
                Else
                    toDisplay = ltext
                End If

                Dim textSize As SizeF = e.Graphics.MeasureString(toDisplay, Font)
                textRect.Width = textSize.Width
                textRect.Height = textSize.Height
                textRect.X = (ClientRectangle.Width - textRect.Width) / 2
                textRect.Y = (ClientRectangle.Height - textRect.Height) / 2
            End If

            e.Graphics.FillRectangle(baseBackground, ClientRectangle)
            e.Graphics.FillRectangle(backgroundDim, toDim)
            e.Graphics.Flush()
            If (toDisplay <> Nothing And toDisplay.Length > 0) Then
                e.Graphics.DrawString(toDisplay, Font, New SolidBrush(ForeColor), textRect)
            End If
        End Sub

        Protected Overrides Sub OnTextChanged(ByVal E As EventArgs)
            MyBase.OnTextChanged(E)
            Invalidate()
        End Sub

        Protected Overrides Sub OnBackColorChanged(ByVal E As EventArgs)
            MyBase.OnTextChanged(E)
            If Not (baseBackground Is Nothing) And Not ShowGradient Then
                baseBackground.Dispose()
                baseBackground = Nothing
            End If
        End Sub

        Protected Overrides Sub OnBackgroundImageChanged(ByVal E As EventArgs)
            MyBase.OnTextChanged(E)
            If Not (baseBackground Is Nothing) And Not ShowGradient Then
                baseBackground.Dispose()
                baseBackground = Nothing
            End If
        End Sub

        Protected Overrides Sub OnResize(ByVal e As EventArgs)
            MyBase.OnResize(e)
            If Not (baseBackground Is Nothing) Then
                baseBackground.Dispose()
                baseBackground = Nothing
            End If
        End Sub

        Protected Overridable Sub OnValueChanged(ByVal e As EventArgs)
            RaiseEvent ValueChanged(Me, e)
        End Sub

        Private Sub SetDragValue(ByVal mouseLocation As Point)

            Dim client As Rectangle = ClientRectangle

            If (client.Contains(mouseLocation)) Then

                Dim percentage As Single = CSng(mouseLocation.X) / CSng(ClientRectangle.Width)
                Dim newDragValue As Integer = CInt(percentage * CSng(Max - Min))

                If (newDragValue <> dragValue) Then
                    Dim old As Integer = dragValue
                    dragValue = newDragValue
                    OptimizedInvalidate(old, dragValue)
                End If

            Else

                If (client.Y <= mouseLocation.Y And mouseLocation.Y <= client.Y + client.Height) Then
                    If (mouseLocation.X <= client.X And mouseLocation.X > client.X - LeftRightBorder) Then
                        Dim newDragValue As Integer = Min
                        If (newDragValue <> dragValue) Then
                            Dim old As Integer = dragValue
                            dragValue = newDragValue
                            OptimizedInvalidate(old, dragValue)
                        End If

                    ElseIf (mouseLocation.X >= client.X + client.Width And mouseLocation.X < client.X + client.Width + LeftRightBorder) Then
                        Dim newDragValue As Integer = Max
                        If (newDragValue <> dragValue) Then
                            Dim old As Integer = dragValue
                            dragValue = newDragValue
                            OptimizedInvalidate(old, dragValue)
                        End If
                    End If

                Else
                    If (dragValue <> Value) Then
                        Dim old As Integer = dragValue
                        dragValue = Value
                        OptimizedInvalidate(old, dragValue)
                    End If

                End If

            End If

        End Sub

    End Class

End Namespace
[C#]
namespace Microsoft.Samples.WinForms.Cs.FlashTrackBar {
    using System;
    using System.ComponentModel;
    using System.ComponentModel.Design;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Drawing.Design;
    using System.Windows.Forms;
    using System.Diagnostics;

    public class FlashTrackBar : System.Windows.Forms.Control {
        /// <summary>
        ///    Required designer variable.
        /// </summary>
        private System.ComponentModel.Container components;

        private const int LeftRightBorder = 10;
        private int value = 0;
        private int min = 0;
        private int max = 100;
        private bool showPercentage = false;
        private bool showValue = false;
        private bool allowUserEdit = true;
        private bool showGradient = true;
        private int dragValue = 0;
        private bool dragging = false;
        private Color startColor = Color.Red;
        private Color endColor = Color.LimeGreen;
        private EventHandler onValueChanged;
        private Brush baseBackground = null;
        private Brush backgroundDim = null;
        private byte darkenBy = 200;


        public FlashTrackBar() {
            //
            // Required for Windows Form designer support.
            //
            InitializeComponent();

            //
            // Add any constructor code after the InitializeComponent call.
            //
            SetStyle(ControlStyles.Opaque, true);
            SetStyle(ControlStyles.ResizeRedraw, true);
            Debug.Assert(GetStyle(ControlStyles.ResizeRedraw), "Should be redraw!");
        }

        /// <summary>
        ///    Clean up any resources being used.
        /// </summary>
        protected override void Dispose(bool disposing) {
   if (disposing) {
        if (components != null) {
            components.Dispose();
        }
   }
   base.Dispose(disposing);
}
        /// <summary>
        ///    Required method for designer support. Do not modify
        ///    the contents of this method with the code editor.
        /// </summary>
        void InitializeComponent () {
            this.components = new System.ComponentModel.Container ();
            this.ForeColor = System.Drawing.Color.White;
            this.BackColor = System.Drawing.Color.Black;
            this.Size = new System.Drawing.Size(100, 23);
            this.Text = "FlashTrackBar";
        }

        [
            Category("Flash"),
            DefaultValue(true)
        ]
        public bool AllowUserEdit {
            get {
                return allowUserEdit;
            }
            set {
                if (value != allowUserEdit) {
                    allowUserEdit = value;
                    if (!allowUserEdit) {
                        Capture = false;
                        dragging = false;
                    }
                }
            }
        }

        [
            Category("Flash")
        ]
        public Color EndColor {
            get {
                return endColor;
            }
            set {
                endColor = value;
                if (baseBackground != null && showGradient) {
                    baseBackground.Dispose();
                    baseBackground = null;
                }
                Invalidate();
            }
        }

        public bool ShouldSerializeEndColor() {
            return !(endColor == Color.LimeGreen);
        }


        [
            Category("Flash"),
            Editor(typeof(FlashTrackBarDarkenByEditor), typeof(UITypeEditor)),
            DefaultValue((byte)200)
        ]
        public byte DarkenBy {
            get {
                return darkenBy;
            }
            set {
                if (value != darkenBy) {
                    darkenBy = value;
                    if (backgroundDim != null) {
                        backgroundDim.Dispose();
                        backgroundDim = null;
                    }
                    OptimizedInvalidate(Value, max);
                }
            }
        }

        [
            Category("Flash"),
            DefaultValue(100)
        ]
        public int Max {
            get {
                return max;
            }
            set {
                if (max != value) {
                    max = value;
                    Invalidate();
                }
            }
        }

        [
            Category("Flash"),
            DefaultValue(0)
        ]
        public int Min {
            get {
                return min;
            }
            set {
                if (min != value) {
                    min = value;
                    Invalidate();
                }
            }
        }

        [
            Category("Flash")
        ]
        public Color StartColor {
            get {
                return startColor;
            }
            set {
                startColor = value;
                if (baseBackground != null && showGradient) {
                    baseBackground.Dispose();
                    baseBackground = null;
                }
                Invalidate();
            }
        }

        public bool ShouldSerializeStartColor() {
            return !(startColor == Color.Red);
        }



        [
            Category("Flash"),
            RefreshProperties(RefreshProperties.Repaint),
            DefaultValue(false)
        ]
        public bool ShowPercentage {
            get {
                return showPercentage;
            }
            set {
                if (value != showPercentage) {
                    showPercentage = value;
                    if (showPercentage) {
                        showValue = false;
                    }
                    Invalidate();
                }
            }
        }

        [
            Category("Flash"),
            RefreshProperties(RefreshProperties.Repaint),
            DefaultValue(false)
        ]
        public bool ShowValue {
            get {
                return showValue;
            }
            set {
                if (value != showValue) {
                    showValue = value;
                    if (showValue) {
                        showPercentage = false;
                    }
                    Invalidate();
                }
            }
        }

        [
            Category("Flash"),
            DefaultValue(true)
        ]
        public bool ShowGradient {
            get {
                return showGradient;
            }
            set {
                if (value != showGradient) {
                    showGradient = value;
                    if (baseBackground != null) {
                        baseBackground.Dispose();
                        baseBackground = null;
                    }
                    Invalidate();
                }
            }
        }

        [
            Category("Flash"),
            Editor(typeof(FlashTrackBarValueEditor), typeof(UITypeEditor)),
            DefaultValue(0)
        ]
        public int Value {
            get {
                if (dragging) {
                    return dragValue;
                }
                return value;
            }
            set {
                if (value != this.value) {
                    int old = this.value;
                    this.value = value;
                    OnValueChanged(EventArgs.Empty);
                    OptimizedInvalidate(old, this.value);
                }
            }
        }

        // ValueChanged Event.
        [Description("Raised when the Value displayed changes")]
        public event EventHandler ValueChanged {
            add {
                onValueChanged += value;
            }
            remove {
                onValueChanged -= value;
            }
        }

        private void OptimizedInvalidate(int oldValue, int newValue) {
            Rectangle client = ClientRectangle;

            float oldPercentValue = ((float)oldValue / ((float)Max - (float)Min));
            int oldNonDimLength = (int)(oldPercentValue * (float)client.Width);

            float newPercentValue = ((float)newValue / ((float)Max - (float)Min));
            int newNonDimLength = (int)(newPercentValue * (float)client.Width);

            int min = Math.Min(oldNonDimLength, newNonDimLength);
            int max = Math.Max(oldNonDimLength, newNonDimLength);

            Rectangle invalid = new Rectangle(client.X + min, client.Y, max - min, client.Height);
            Invalidate(invalid);

            string oldToDisplay;
            string newToDisplay;

            if (ShowPercentage) {
                oldToDisplay = Convert.ToString((int)(oldPercentValue * 100f)) + "%";
                newToDisplay = Convert.ToString((int)(newPercentValue * 100f)) + "%";
            }
            else if (ShowValue) {
                oldToDisplay = Convert.ToString(oldValue);
                newToDisplay = Convert.ToString(newValue);
            }
            else {
                oldToDisplay = null;
                newToDisplay = null;
            }

            if (oldToDisplay != null && newToDisplay != null) {
                Graphics g = CreateGraphics();
                SizeF oldFontSize = g.MeasureString(oldToDisplay, Font);
                SizeF newFontSize = g.MeasureString(newToDisplay, Font);
                RectangleF oldFontRect = new RectangleF(new PointF(0, 0), oldFontSize);
                RectangleF newFontRect = new RectangleF(new PointF(0, 0), newFontSize);
                oldFontRect.X = (client.Width - oldFontRect.Width) / 2;
                oldFontRect.Y = (client.Height - oldFontRect.Height) / 2;
                newFontRect.X = (client.Width - newFontRect.Width) / 2;
                newFontRect.Y = (client.Height - newFontRect.Height) / 2;

                Invalidate(new Rectangle((int)oldFontRect.X, (int)oldFontRect.Y, (int)oldFontRect.Width, (int)oldFontRect.Height));
                Invalidate(new Rectangle((int)newFontRect.X, (int)newFontRect.Y, (int)newFontRect.Width, (int)newFontRect.Height));
            }
        }


        protected override void OnMouseDown(MouseEventArgs e) {
            base.OnMouseDown(e);
            if (!allowUserEdit) {
                return;
            }
            Capture = true;
            dragging = true;
            SetDragValue(new Point(e.X, e.Y));
        }

        protected override void OnMouseMove(MouseEventArgs e) {
            base.OnMouseMove(e);
            if (!allowUserEdit || !dragging) {
                return;
            }
            SetDragValue(new Point(e.X, e.Y));
        }

        protected override void OnMouseUp(MouseEventArgs e) {
            base.OnMouseUp(e);
            if (!allowUserEdit || !dragging) {
                return;
            }
            Capture = false;
            dragging = false;
            value = dragValue;
            OnValueChanged(EventArgs.Empty);
        }

        protected override void OnPaint(PaintEventArgs e) {
            base.OnPaint(e);
            if (baseBackground == null) {
                if (showGradient) {
                    baseBackground = new LinearGradientBrush(new Point(0, 0),
                                                             new Point(ClientSize.Width, 0),
                                                             StartColor,
                                                             EndColor);
                }
                else if (BackgroundImage != null) {
                    baseBackground = new TextureBrush(BackgroundImage);
                }
                else {
                    baseBackground = new SolidBrush(BackColor);
                }
            }

            if (backgroundDim == null) {
                backgroundDim = new SolidBrush(Color.FromArgb(DarkenBy, Color.Black));
            }

            Rectangle toDim = ClientRectangle;
            float percentValue = ((float)Value / ((float)Max - (float)Min));
            int nonDimLength = (int)(percentValue * (float)toDim.Width);
            toDim.X += nonDimLength;
            toDim.Width -= nonDimLength;


            string text = Text;
            string toDisplay = null;
            RectangleF textRect = new RectangleF();

            if (ShowPercentage || ShowValue || text.Length > 0) {

                if (ShowPercentage) {
                    toDisplay = Convert.ToString((int)(percentValue * 100f)) + "%";
                }
                else if (ShowValue) {
                    toDisplay = Convert.ToString(Value);
                }
                else {
                    toDisplay = text;
                }

                SizeF textSize = e.Graphics.MeasureString(toDisplay, Font);
                textRect.Width = textSize.Width;
                textRect.Height = textSize.Height;
                textRect.X = (ClientRectangle.Width - textRect.Width) / 2;
                textRect.Y = (ClientRectangle.Height - textRect.Height) / 2;
            }

            e.Graphics.FillRectangle(baseBackground, ClientRectangle);
            e.Graphics.FillRectangle(backgroundDim, toDim);
            e.Graphics.Flush();
            if (toDisplay != null && toDisplay.Length > 0) {
                e.Graphics.DrawString(toDisplay, Font, new SolidBrush(ForeColor), textRect);
            }
        }

        protected override void OnTextChanged(EventArgs e) {
            base.OnTextChanged(e);
            Invalidate();
        }

        protected override void OnBackColorChanged(EventArgs e) {
            base.OnTextChanged(e);
            if ((baseBackground != null) && (!showGradient)) {
                        baseBackground.Dispose();
                        baseBackground = null;
            }
        }

        protected override void OnBackgroundImageChanged(EventArgs e) {
            base.OnTextChanged(e);
            if ((baseBackground != null) && (!showGradient)) {
                        baseBackground.Dispose();
                        baseBackground = null;
            }
        }

        protected override void OnResize(EventArgs e) {
            base.OnResize(e);
            if (baseBackground != null) {
                baseBackground.Dispose();
                baseBackground = null;
            }
        }

        protected virtual void OnValueChanged(EventArgs e) {
            if (onValueChanged != null) {
                onValueChanged.Invoke(this, e);
            }
        }

        private void SetDragValue(Point mouseLocation) {

            Rectangle client = ClientRectangle;

            if (client.Contains(mouseLocation)) {
                float percentage = (float)mouseLocation.X / (float)ClientRectangle.Width;
                int newDragValue = (int)(percentage * (float)(max - min));
                if (newDragValue != dragValue) {
                    int old = dragValue;
                    dragValue = newDragValue;
                    OptimizedInvalidate(old, dragValue);
                }
            }
            else {
                if (client.Y <= mouseLocation.Y && mouseLocation.Y <= client.Y + client.Height) {
                    if (mouseLocation.X <= client.X && mouseLocation.X > client.X - LeftRightBorder) {
                        int newDragValue = min;
                        if (newDragValue != dragValue) {
                            int old = dragValue;
                            dragValue = newDragValue;
                            OptimizedInvalidate(old, dragValue);
                        }
                    }
                    else if (mouseLocation.X >= client.X + client.Width && mouseLocation.X < client.X + client.Width + LeftRightBorder) {
                        int newDragValue = max;
                        if (newDragValue != dragValue) {
                            int old = dragValue;
                            dragValue = newDragValue;
                            OptimizedInvalidate(old, dragValue);
                        }
                    }
                }
                else {
                    if (dragValue != value) {
                        int old = dragValue;
                        dragValue = value;
                        OptimizedInvalidate(old, dragValue);
                    }
                }
            }
        }
    }
}

Vedere anche

Sviluppo di controlli Windows Form