共用方式為


HOW TO:建立顯示進度的 Windows Form 控制項

下列程式碼範例會示範名為 FlashTrackBar、可用來顯示應用程式層級或進度給使用者的自訂控制項。 它使用漸層以視覺化方式表示進度。

FlashTrackBar 控制項將說明下列的概念。

  • 定義自訂屬性。

  • 定義自訂事件 (FlashTrackBar 會定義 ValueChanged 事件)。

  • 覆寫 OnPaint 方法以提供描繪控制項的邏輯。

  • 使用控制項的 ClientRectangle 屬性來計算可供描繪的區域。 FlashTrackBar 則在其 OptimizedInvalidate 方法中執行這項工作。

  • 當屬性在 Windows Form 設計工具中變更後,實作該屬性的序列化或持續性。 FlashTrackBar 會定義 ShouldSerializeStartColor 和 ShouldSerializeEndColor 方法以序列化其 StartColor 和 EndColor 屬性。

下列資料表顯示由 FlashTrackBar 所定義的自訂屬性。

屬性

描述

AllowUserEdit

表示使用者是否可以經由按一下並拖曳快速追蹤列的方式來變更它的值。

EndColor

指定追蹤列的結束色彩。

DarkenBy

指定相較於前景漸層的背景暗度。

Max

指定追蹤列的最大值。

Min

指定追蹤列的最小值。

StartColor

指定漸層的起始色彩。

ShowPercentage

表示是否要顯示漸層的百分比。

ShowValue

表示是否要顯示漸層的目前值。

ShowGradient

表示追蹤列是否要顯示目前值的色彩漸層。

  • Value

指定追蹤列的目前值。

下列資料表顯示由屬性變更事件 FlashTrackBar: 和引發該事件的方法所定義的其他成員。

成員

描述

ValueChanged

當追蹤列的 Value 屬性變更時所引發的事件。

OnValueChanged

會引發 ValueChanged 事件的方法。

注意事項注意事項

FlashTrackBar 使用事件資料的 EventArgs 類別和事件委派 (Delegate) 的 EventHandler

若要處理對應的 EventName 事件,FlashTrackBar 會覆寫下列繼承自 System.Windows.Forms.Control 的方法:

若要處理對應的屬性變更事件,FlashTrackBar 會覆寫下列繼承自 System.Windows.Forms.Control 的方法。

範例

FlashTrackBar 控制項定義了顯示於下列程式碼清單中的兩個 UI 型別編輯器 (FlashTrackBarValueEditor 和 FlashTrackBarDarkenByEditor)。 HostApp 類別使用在 Window Form 上的 FlashTrackBar 控制項。

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

    <System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.Demand, Name:="FullTrust")> _
    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()

            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(ByVal disposing As Boolean)
            If disposing Then
                If (components IsNot Nothing) Then
                    components.Dispose()
                End If
            End If
            MyBase.Dispose(disposing)
        End Sub


#Region " Windows Form Designer generated code "

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

        'NOTE: The following procedure is required by the Windows Form Designer
        'It can be modified using the Windows Form 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 ((baseBackground IsNot Nothing) And myShowGradient) Then
                    baseBackground.Dispose()
                    baseBackground = Nothing
                End If
                Invalidate()
            End Set
        End Property


        Public Function ShouldPersistEndColor() 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 (backgroundDim IsNot 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 ((baseBackground IsNot Nothing) And myShowGradient) Then
                    baseBackground.Dispose()
                    baseBackground = Nothing
                End If
                Invalidate()
            End Set
        End Property

        Public Function ShouldPersistStartColor() 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 (baseBackground IsNot 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 (BackgroundImage IsNot 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.OnBackColorChanged(E)
            If (baseBackground IsNot 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 (baseBackground IsNot 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 (baseBackground IsNot 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
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;

    [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")] 
    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();

            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.OnBackColorChanged(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);
                    }
                }
            }
        }
    }
}
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 FlashTrackBarDarkenByEditor 
        Inherits FlashTrackBarValueEditor 

       Overrides Protected Sub SetEditorProps(editingInstance As FlashTrackBar, editor As FlashTrackBar) 
           MyBase.SetEditorProps(editingInstance, editor)
           editor.Min = 0
           editor.Max = System.Byte.MaxValue
       End Sub

   End Class

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

   public class FlashTrackBarDarkenByEditor : FlashTrackBarValueEditor {
       protected override void SetEditorProps(FlashTrackBar editingInstance, FlashTrackBar editor) {
           base.SetEditorProps(editingInstance, editor);
           editor.Min = 0;
           editor.Max = byte.MaxValue;
       }
   }
}

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
Imports System.Windows.Forms.ComponentModel
Imports System.Windows.Forms.Design

Namespace Microsoft.Samples.WinForms.VB.FlashTrackBar

    <System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.Demand, Name:="FullTrust")> _
    Public Class FlashTrackBarValueEditor
        Inherits UITypeEditor

        Private edSvc As IWindowsFormsEditorService


        Overridable Protected Sub SetEditorProps(editingInstance As FlashTrackBar, editor As FlashTrackBar)
            editor.ShowValue = true
            editor.StartColor = Color.Navy
            editor.EndColor = Color.White
            editor.ForeColor = Color.White
            editor.Min = editingInstance.Min
            editor.Max = editingInstance.Max
        End Sub

        Overrides OverLoads Public Function EditValue(context As ITypeDescriptorContext, provider As IServiceProvider, value As object) As Object

            If ((context IsNot Nothing) And (context.Instance IsNot Nothing) And (provider IsNot Nothing)) Then

                edSvc = CType(provider.GetService(GetType(IWindowsFormsEditorService)), IWindowsFormsEditorService)

                If (edSvc IsNot Nothing) Then

                    Dim trackBar As FlashTrackBar = New FlashTrackBar()
                    AddHandler trackBar.ValueChanged, AddressOf Me.ValueChanged
                    SetEditorProps(CType(context.Instance, FlashTrackBar), TrackBar)

                    Dim asInt As Boolean = True

                    If (TypeOf value Is Integer) Then
                        trackBar.Value = CInt(value)
                    ElseIf (TypeOf value Is System.Byte) Then
                        asInt = False
                        trackBar.Value = CType(value, Byte)
                    End If

                    edSvc.DropDownControl(trackBar)

                    If (asInt) Then
                        value = trackBar.Value
                    Else
                        value = CType(trackBar.Value, Byte)
                    End If

                End If

            End If

            Return value

         End Function

        Overrides OverLoads Public Function GetEditStyle(context As ITypeDescriptorContext) As UITypeEditorEditStyle
            If ((context IsNot Nothing) And (context.Instance IsNot Nothing)) Then
                Return UITypeEditorEditStyle.DropDown
            End If
            Return MyBase.GetEditStyle(context)
        End Function

        private Sub ValueChanged(sender As object, e As EventArgs)
            If (edSvc IsNot Nothing) Then
                edSvc.CloseDropDown()
            End If
        End Sub

    End Class

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

    [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")] 
    public class FlashTrackBarValueEditor : System.Drawing.Design.UITypeEditor {

        private IWindowsFormsEditorService edSvc = null;

        protected virtual void SetEditorProps(FlashTrackBar editingInstance, FlashTrackBar editor) {
            editor.ShowValue = true;
            editor.StartColor = Color.Navy;
            editor.EndColor = Color.White;
            editor.ForeColor = Color.White;
            editor.Min = editingInstance.Min;
            editor.Max = editingInstance.Max;
        }

        public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) {

            if (context != null
                && context.Instance != null
                && provider != null) {

                edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));

                if (edSvc != null) {
                    FlashTrackBar trackBar = new FlashTrackBar();
                    trackBar.ValueChanged += new EventHandler(this.ValueChanged);
                    SetEditorProps((FlashTrackBar)context.Instance, trackBar);
                    bool asInt = true;
                    if (value is int) {
                        trackBar.Value = (int)value;
                    }
                    else if (value is byte) {
                        asInt = false;
                        trackBar.Value = (byte)value;
                    }
                    edSvc.DropDownControl(trackBar);
                    if (asInt) {
                        value = trackBar.Value;
                    }
                    else {
                        value = (byte)trackBar.Value;
                    }
                }
            }

            return value;
        }

        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) {
            if (context != null && context.Instance != null) {
                return UITypeEditorEditStyle.DropDown;
            }
            return base.GetEditStyle(context);
        }

        private void ValueChanged(object sender, EventArgs e) {
            if (edSvc != null) {
                edSvc.CloseDropDown();
            }
        }
    }
}

Imports System
Imports System.ComponentModel
Imports System.Drawing
Imports System.Windows.Forms
Imports Microsoft.Samples.WinForms.VB.FlashTrackBar


Namespace Microsoft.Samples.WinForms.VB.HostApp

    Public Class HostApp
        Inherits System.Windows.Forms.Form

        Public Sub New()

            MyBase.New()

            HostApp = Me

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

        End Sub

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



#Region " Windows Form Designer generated code "

        'Required by the Windows Form Designer
        Private components As System.ComponentModel.Container
        Private WithEvents flashTrackBar1 As Microsoft.Samples.WinForms.VB.FlashTrackBar.FlashTrackBar

        Private WithEvents HostApp As System.Windows.Forms.Form

        'NOTE: The following procedure is required by the Windows Form Designer
        'It can be modified using the Windows Form Designer.
        'Do not modify it using the code editor.
        Private Sub InitializeComponent()
            Me.components = New System.ComponentModel.Container()
            Me.flashTrackBar1 = New Microsoft.Samples.WinForms.VB.FlashTrackBar.FlashTrackBar()

            flashTrackBar1.Dock = System.Windows.Forms.DockStyle.Fill
            flashTrackBar1.ForeColor = System.Drawing.Color.White
            flashTrackBar1.BackColor = System.Drawing.Color.Black
            flashTrackBar1.Size = New System.Drawing.Size(600, 450)
            flashTrackBar1.TabIndex = 0
            flashTrackBar1.Value = 73
            flashTrackBar1.Text = "Drag the Mouse and say Wow!"

            Me.Text = "Control Example"
            Me.ClientSize = New System.Drawing.Size(528, 325)

            Me.Controls.Add(flashTrackBar1)

        End Sub

#End Region

        'The main entry point for the application
        <STAThread()> Shared Sub Main()
            System.Windows.Forms.Application.Run(New HostApp())
        End Sub

    End Class

End Namespace

namespace Microsoft.Samples.WinForms.Cs.HostApp {
    using System;
    using System.ComponentModel;
    using System.Drawing;
    using System.Windows.Forms;
    using Microsoft.Samples.WinForms.Cs.FlashTrackBar;

    public class HostApp : System.Windows.Forms.Form {
        /// <summary>
        ///    Required designer variable.
        /// </summary>
        private System.ComponentModel.Container components;
        protected internal Microsoft.Samples.WinForms.Cs.FlashTrackBar.FlashTrackBar flashTrackBar1;

        public HostApp() {
            //
            // Required for Windows Form Designer support
            //
            InitializeComponent();

        }

        /// <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>
        private void InitializeComponent() {
            this.components = new System.ComponentModel.Container ();
            this.flashTrackBar1 = new Microsoft.Samples.WinForms.Cs.FlashTrackBar.FlashTrackBar ();
            this.Text = "Control Example";
            this.ClientSize = new System.Drawing.Size (600, 450);
            flashTrackBar1.BackColor = System.Drawing.Color.Black;
            flashTrackBar1.Dock = System.Windows.Forms.DockStyle.Fill;
            flashTrackBar1.TabIndex = 0;
            flashTrackBar1.ForeColor = System.Drawing.Color.White;
            flashTrackBar1.Text = "Drag the Mouse and say Wow!";
            flashTrackBar1.Value = 73;
            flashTrackBar1.Size = new System.Drawing.Size (600, 450);
            this.Controls.Add (this.flashTrackBar1);
        }

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        public static void Main(string[] args) {
            Application.Run(new HostApp());
        }

    }
}

請參閱

概念

Windows Form 控制項開發的基本概念

其他資源

擴充設計階段支援