How to: Create a Windows Forms Control That Shows Progress
The following code example shows a custom control called FlashTrackBar that can be used to show the user the level or the progress of an application. It uses a gradient to visually represent progress.
The FlashTrackBar control illustrates the following concepts:
Defining custom properties.
Defining custom events. (FlashTrackBar defines the ValueChanged event.)
Overriding the OnPaint method to provide logic to draw the control.
Computing the area available for drawing the control by using its ClientRectangle property. FlashTrackBar does this in its OptimizedInvalidate method.
Implementing serialization or persistence for a property when it is changed in the Windows Forms Designer. FlashTrackBar defines the ShouldSerializeStartColor and ShouldSerializeEndColor methods for serializing its StartColor and EndColor properties.
The following table shows the custom properties defined by FlashTrackBar.
Property |
Description |
---|---|
AllowUserEdit |
Indicates whether the user can change the value of the flash track bar by clicking and dragging it. |
EndColor |
Specifies the ending color of the track bar. |
DarkenBy |
Specifies how much to darken the background with respect to the foreground gradient. |
Max |
Specifies the maximum value of the track bar. |
Min |
Specifies the minimum value of the track bar. |
StartColor |
Specifies the starting color of the gradient. |
ShowPercentage |
Indicates whether to display a percentage over the gradient. |
ShowValue |
Indicates whether to display the current value over the gradient. |
ShowGradient |
Indicates whether the track bar should display a color gradient showing the current value. |
|
Specifies the current value of the track bar. |
The following table shows additional members defined by FlashTrackBar: the property-changed event and the method that raises the event.
Member |
Description |
---|---|
ValueChanged |
The event that is raised when the Value property of the track bar changes. |
OnValueChanged |
The method that raises the ValueChanged event. |
Note
FlashTrackBar uses the EventArgs class for event data and EventHandler for the event delegate.
To handle the corresponding EventName events, FlashTrackBar overrides the following methods that it inherits from System.Windows.Forms.Control:
To handle the corresponding property-changed events, FlashTrackBar overrides the following methods that it inherits from System.Windows.Forms.Control:
Example
The FlashTrackBar control defines two UI type editors, FlashTrackBarValueEditor and FlashTrackBarDarkenByEditor, which are shown in the following code listings. The HostApp class uses the FlashTrackBar control on a Windows Form.
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());
}
}
}
See Also
Concepts
Windows Forms Control Development Basics