Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
189 views

gTrackBar - A Custom TrackBar UserControl (VB - NET) - CodeProject

This document describes a custom TrackBar user control created in VB.NET that provides additional functionality over the standard TrackBar. It allows customizing the appearance, adding value display, labels, and increment buttons. The control draws each element and handles interactions like highlighting the value as the user moves the slider.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
189 views

gTrackBar - A Custom TrackBar UserControl (VB - NET) - CodeProject

This document describes a custom TrackBar user control created in VB.NET that provides additional functionality over the standard TrackBar. It allows customizing the appearance, adding value display, labels, and increment buttons. The control draws each element and handles interactions like highlighting the value as the user moves the slider.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 13

06/10/2022, 16:25 gTrackBar - A Custom TrackBar UserControl (VB.

NET) - CodeProject

15,444,824 members 533 ☰

articles Q&A forums stuff lounge ? Search for articles, questions,

Watch

gTrackBar - A Custom TrackBar


UserControl (VB.NET)
SSDiver2112 Rate me: 4.94/5 (62 votes)

17 Mar 2015 CPOL

TrackBar with custom coloring, value display, label, and increment buttons.

Is your email address OK? You are signed up for our newsletters but your email
address is either unconfirmed, or has not been reconfirmed in a long time. Please
click here to have a confirmation email sent so we can confirm your email address
and start sending you newsletters again. Alternatively, you can update your
subscriptions.

Download gTrackBar.zip

https://www.codeproject.com/Articles/35104/gTrackBar-A-Custom-TrackBar-UserControl-VB-NET 1/13
06/10/2022, 16:25 gTrackBar - A Custom TrackBar UserControl (VB.NET) - CodeProject

Introduction
I must have OCD (Obsessive Control Disorder). The standard TrackBar has annoyed me for a long
time, but I just put up with it until now. I finally got tired of the boring appearance, having to code
a TextBox or Label with it to display the value, and a Label for what it is. So, here is the TrackBar
https://www.codeproject.com/Articles/35104/gTrackBar-A-Custom-TrackBar-UserControl-VB-NET 2/13
06/10/2022, 16:25 gTrackBar - A Custom TrackBar UserControl (VB.NET) - CodeProject

I needed, hope it helps you too. There are too many properties to just list them out like I normally
would, so I decided to list the function of the property groups and a screenshot of the whole list.

1. The Control group contains the control's Border, Value, and Orientation properties.
2. FloatValue is the value that appears as the slider is moved with the mouse.
3. Label is the text that appears above the TrackBar.
4. Slider is the line, tick marks, and the slider button itself.
5. UpDownButtons are the buttons at each end of the TrackBar to increment the value by one.
6. ValueBox is the box displaying the value.

Properties

https://www.codeproject.com/Articles/35104/gTrackBar-A-Custom-TrackBar-UserControl-VB-NET 3/13
06/10/2022, 16:25 gTrackBar - A Custom TrackBar UserControl (VB.NET) - CodeProject

The Building Region contains the routines to setup the layout, size, and positions for all parts of the
control based on the properties set.

Painting
Override the Paint event to custom draw each piece of the control in the right place with the
correct orientation.

VB.NET Shrink ▲

Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)

MyBase.OnPaint(e)

'Setup the Graphics


Dim g As Graphics = e.Graphics
g.SmoothingMode = SmoothingMode.AntiAlias
g.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAlias

'Draw a Border around the control if requested


If _BorderShow Then
g.DrawRectangle(New Pen(_BorderColor), _
0, 0, Me.Width - 1, Me.Height - 1)
End If

'Add the value increment buttons if requested


If _UpDownShow Then DrawUpDnButtons(g)
'Add the Line and Tick Marks
DrawSliderLine(g)

'Draw the Label Text if requested


If _LabelShow Then
DrawLabel(g)
'g.DrawRectangle(Pens.Gray, rectLabel)
End If

'Add the Slider button


DrawSlider(g)

'Draw the Value above the Slider if requested


If _FloatValue AndAlso IsOverSlider AndAlso _
MouseState = eMouseState.Down Then
DrawFloatValue(g)
End If

'Draw the Box displaying the value if requested


If Not _ValueBox = eValueBox.None Then
DrawValueBox(g)
End If

'Draw Focus Rectangle around control if requested


If _ShowFocus AndAlso Me.Focused Then
ControlPaint.DrawFocusRectangle(g, New Rectangle( _
2 + CInt(Not _BorderShow), 2 + CInt(Not _BorderShow), _
Me.Width - ((2 + CInt(Not _BorderShow)) * 2), _
Me.Height - ((2 + CInt(Not _BorderShow)) * 2)), _
Color.Black, Me.BackColor)

https://www.codeproject.com/Articles/35104/gTrackBar-A-Custom-TrackBar-UserControl-VB-NET 4/13
06/10/2022, 16:25 gTrackBar - A Custom TrackBar UserControl (VB.NET) - CodeProject

End If
End Sub

I used basic GDI+ functions to draw each piece of the control. I will highlight some of the better
parts.

In DrawUpDnButtons, I basically have a button that needs to be drawn one of four ways depending
on the Orientation and which side of the control it is on. The button itself is just a rectangle with
a gradient color fill. The trick was the arrow. I could have calculated each arrow position and points
to create a separate GraphicsPath for each, but I used a Matrix instead to Rotate and/or
Translate a simple GraphicsPath to the right position.

First set three points and add a line between them to create the triangular arrow ^ shape:

VB
Dim gp As New GraphicsPath
Dim pts() As Point
Dim mx As New Matrix

pts = New Point() { _


New Point(5, 0), _
New Point(0, 5), _
New Point(5, 10)}
gp.AddLines(pts)

For the left hand button, the GraphicsPath is oriented correctly so it just needs to be translated
(moved) to the right position inside the button's rectangle.

VB
With rectDownButton

mx.Translate(5, CSng((rectDownButton.Y _
+ (rectDownButton.Height / 2)) - 6))
gp.Transform(mx)
g.DrawPath(pn, gp)

End With

For the right hand button, the GraphicsPath needs to be flipped, but there isn't a built-in function
for flipping. Use this to flip the GraphicsPath horizontally instead: New Matrix(-1, 0, 0, 1,
image width here, 0).

VB.NET
With rectUpButton
mx = New Matrix(-1, 0, 0, 1, 5, 0)
mx.Translate(.X + 9, 0, MatrixOrder.Append)
gp.Transform(mx)
g.DrawPath(pn, gp)
End With

https://www.codeproject.com/Articles/35104/gTrackBar-A-Custom-TrackBar-UserControl-VB-NET 5/13
06/10/2022, 16:25 gTrackBar - A Custom TrackBar UserControl (VB.NET) - CodeProject

For the upper button, the GraphicsPath needs to be rotated 90 degrees. Find the center point and
RotateAt that point.

VB
With rectDownButton

mx.RotateAt(90, New PointF(gp.GetBounds.Width / 2, _


gp.GetBounds.Height / 2))

mx.Translate(CSng((rectDownButton.X + _
(rectDownButton.Width / 2)) - 3), 4, MatrixOrder.Append)

gp.Transform(mx)
g.DrawPath(pn, gp)
End With

For the lower button, the GraphicsPath needs to be flipped again. Use this to flip the image
vertically: New Matrix(1, 0, 0, -1, 0, image height here).

VB.NET
With rectUpButton
mx = New Matrix(1, 0, 0, -1, 0, 10)
mx.Translate(0, .Y + 6, MatrixOrder.Append)
gp.Transform(mx)
g.DrawPath(pn, gp)
End With

Custom Type Converters


The CenterPoint and FocusScales used in the slider brushes are of type PointF. When you create
a new property of type PointF, you will notice that it is grayed out in the PropertyGrid, but if a
property is of type Point, it will edit correctly in the PropertyGrid. The problem is that there is no
built-in TypeConverter for PointF. This is actually pretty easy to fix.

A PointF type property without a custom TypeConverter: it works in code, but you cannot edit it
in the PropertyGrid.

With the PointFConverter, it performs just like the Point property in the PropertyGrid.

Create a property and add the TypeConverter attribute referencing the PointFConverter class we
are about to add.

VB
https://www.codeproject.com/Articles/35104/gTrackBar-A-Custom-TrackBar-UserControl-VB-NET 6/13
06/10/2022, 16:25 gTrackBar - A Custom TrackBar UserControl (VB.NET) - CodeProject

Private _SliderHighlightPt As PointF = New PointF(-5.0F, -2.5F)


<Category("Appearance Slider")> _
<Description("Point on the Slider for the Highlight Color")> _
<TypeConverter(GetType(PointFConverter))> _
Public Property SliderHighlightPt() As PointF
Get
Return _SliderHighlightPt
End Get
Set(ByVal value As PointF)
_SliderHighlightPt = value
Me.Invalidate()
End Set
End Property

The PointFConverter class inherits ExpandableObjectConverter, and overrides the


CanConvertFrom, ConvertFrom, and ConvertTo functions.

VB Shrink ▲

Friend Class PointFConverter : Inherits ExpandableObjectConverter

Public Overloads Overrides Function CanConvertFrom( _


ByVal context As System.ComponentModel.ITypeDescriptorContext, _
ByVal sourceType As System.Type) As Boolean

If (sourceType Is GetType(String)) Then


Return True
End If
Return MyBase.CanConvertFrom(context, sourceType)
End Function

Public Overloads Overrides Function ConvertFrom( _


ByVal context As System.ComponentModel.ITypeDescriptorContext, _
ByVal culture As System.Globalization.CultureInfo, _
ByVal value As Object) As Object

If TypeOf value Is String Then


Try
Dim s As String = CType(value, String)
Dim ConverterParts(2) As String
ConverterParts = Split(s, ",")
If Not IsNothing(ConverterParts) Then
If IsNothing(ConverterParts(0)) Then ConverterParts(0) = "-5"
If IsNothing(ConverterParts(1)) Then ConverterParts(1) = "-2.5"
Return New PointF(CSng(ConverterParts(0).Trim), _
CSng(ConverterParts(1).Trim))
End If
Catch ex As Exception
Throw New ArgumentException("Can not convert '" & _
CStr(value) & "' to type Corners")
End Try
Else
Return New PointF(-5.0F, -2.5F)
End If

Return MyBase.ConvertFrom(context, culture, value)


End Function

https://www.codeproject.com/Articles/35104/gTrackBar-A-Custom-TrackBar-UserControl-VB-NET 7/13
06/10/2022, 16:25 gTrackBar - A Custom TrackBar UserControl (VB.NET) - CodeProject

Public Overloads Overrides Function ConvertTo( _


ByVal context As System.ComponentModel.ITypeDescriptorContext, _
ByVal culture As System.Globalization.CultureInfo, _
ByVal value As Object, ByVal destinationType As System.Type) As Object

If (destinationType Is GetType(System.String) _
AndAlso TypeOf value Is PointF) Then

Dim ConverterProperty As PointF = CType(value, PointF)


' build the string representation
Return String.Format("{0}, {1}", _
ConverterProperty.X, _
ConverterProperty.Y)
End If
Return MyBase.ConvertTo(context, culture, value, destinationType)
End Function
End Class 'PointFConverter Class

Custom Color Type Converters

Sometimes with custom controls the properties can get a bit unwieldy. There are a lot of color
choices with this control and some of them have repeating patterns. For example, the Slider button
has three states and three properties (Face, Border, and Highlight). Instead of having nine colors
listed in a long line of confusing properties, they are grouped into three expandable properties
with three sub properties each. The ColorPack class and TypeConverter is used for the three slider
state properties. The ColorLinearGradient class and TypeConveter is used for the Linear gradient
properties of the slider lines. This makes the PropertyGrid look cleaner and easier to read.

Mouse Events
Here is where we check what part of the control the cursor is over and if the mouse button is
pressed. Based on this information, the Value is adjusted accordingly.

Because the MouseDown, Click and so on are a one time deal, a Timer is needed see if the mouse is
still down and if so change the value again. I didn't want it to run away as soon as it was clicked so
there is a built in delay right after the mouse is clicked, then after the delay it will begin
incrementing the value. The other issue is if the Min/Max span was big it would crawl super slow
and small spans would zip too fast, so the Timer's interval is adjusted based on how big the span
is.

https://www.codeproject.com/Articles/35104/gTrackBar-A-Custom-TrackBar-UserControl-VB-NET 8/13
06/10/2022, 16:25 gTrackBar - A Custom TrackBar UserControl (VB.NET) - CodeProject

VB
Private Sub MouseTimer_Tick(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles MouseTimer.Tick

'Check if mouse was just clicked


If MouseHoldDownTicker < 5 Then
MouseHoldDownTicker += 1
'Interval was set to 100 on MouseDown
'Tick off 5 times and then reset the Timer Interval
' based on the Min/Max span
If MouseHoldDownTicker = 5 Then
MouseTimer.Interval = CInt(Math.Max _
(10, 100 - ((_MaxValue - _MinValue) / 10)))
End If
Else
'Change the value until the mouse is released
OldValue = _Value
Value += MouseHoldDownChange
RaiseEvent Scroll(Me, New ScrollEventArgs( ScrollType, oldValue,
_Value, CType(Me.Orientation, ScrollOrientation)))
End If
End Sub

Key Events
I wanted to be able to adjust the Value by pressing the arrow keys. That sounded simple. I figured I
would just check the e.KeyValue in the KeyUp event and adjust the Value accordingly. Well, not so
simple. The problem is that the UserControl Inherits Button, which automatically handles the
arrow keys differently. After the KeyUp event, the focus jumps to the next control in the Tab Order,
even if you use e.Handled and e.SuppressKeyPress. I couldn't stop the focus change. Then, I
thought I would use the KeyDown event, but guess what, the arrows are automatically ignored
there. To fix this behavior, I override the IsInputKey function to allow the arrow keys. After this, the
focus will not jump away anymore.

VB Shrink ▲

Protected Overrides Function IsInputKey( _


ByVal keyData As System.Windows.Forms.Keys) As Boolean

'Because a Usercontrol ignores the arrows in the KeyDown Event


'and changes focus no matter what in the KeyUp Event
'This is needed to fix the KeyDown problem
Select Case keyData And Keys.KeyCode
Case Keys.Up, Keys.Down, Keys.Right, Keys.Left
Return True
Case Else
Return MyBase.IsInputKey(keyData)
End Select
End Function

Private Sub gTrackBar_KeyUp(ByVal sender As Object, _


ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyUp

OldValue = _Value

https://www.codeproject.com/Articles/35104/gTrackBar-A-Custom-TrackBar-UserControl-VB-NET 9/13
06/10/2022, 16:25 gTrackBar - A Custom TrackBar UserControl (VB.NET) - CodeProject

Dim adjust As Integer = _ChangeSmall


If e.Shift Then
adjust = _ChangeLarge
End If

Select Case e.KeyValue


Case Keys.Up, Keys.Right
Value += adjust
If e.Shift Then
ScrollType = ScrollEventType.LargeIncrement
Else
ScrollType = ScrollEventType.SmallIncrement
End If

Case Keys.Down, Keys.Left


Value -= adjust
If e.Shift Then
ScrollType = ScrollEventType.LargeDecrement
Else
ScrollType = ScrollEventType.SmallDecrement
End If
End Select
RaiseEvent Scroll(Me, New ScrollEventArgs(ScrollType, OldValue,
_Value, CType(Me.Orientation, ScrollOrientation)))

End Sub

History
Version 1.0 - March 2009
Version 1.2 - April 2009
Added Focus Rectangle
Separated the label into its own rectangle area for better layout and sizing
General Layout Fixes

Version 1.3 - April 2009


Handles Negative ranges
Version 1.4 - July 2010

Added Image Slider


Added UpDownShow to hide and turn off the Up/Down buttons
Added Timer for changing the value (after a short delay) until the mouse is released
Version 1.5 - July 2011
Added JumpToMouse
Fixed Tick alignment issue when Label shown
Added SnapToValue property

Version 1.6 - September 2011

Added ValueDivisor and ValueAdjusted to allow decimal values


Fixed Vertical version when minimum is greater than 0
https://www.codeproject.com/Articles/35104/gTrackBar-A-Custom-TrackBar-UserControl-VB-NET 10/13
06/10/2022, 16:25 gTrackBar - A Custom TrackBar UserControl (VB.NET) - CodeProject

Version 1.7 - February 2012


Combined Up, Down, and Hover color properties to separate ColorPack class
Added default values to properties
Version 1.8 - April 2012

ColorLinearGradient class for coloring the slider lines


Fixed some layout bugs
Added TickThickness and TickOffset properties

Version 1.9 - March 2015


Added Scroll Event Many people requested the Scroll Event. The ValueChanged
Event was all I needed when I first made the control, but I got curious about it so here
it is.
Added MouseWheel Support.

License
This article, along with any associated source code and files, is licensed under The Code Project
Open License (CPOL)

Written By

SSDiver2112
Software Developer
United States

I first got hooked on programing with the TI994A. After it finally lost all support I reluctantly moved
to the Apple IIe. Thank You BeagleBros for getting me through. I wrote programs for my Scuba
buisness during this time. Currently I am a Database manager and software developer. I started
with VBA and VB6 and now having fun with VB.NET/WPF/C#...

Watch

Comments and Discussions

Add a Comment or Question Email Alerts Search Comments

First Prev Next

Just wonderful
Filip D. Williams 16-Jul-21 2:17
https://www.codeproject.com/Articles/35104/gTrackBar-A-Custom-TrackBar-UserControl-VB-NET 11/13
06/10/2022, 16:25 gTrackBar - A Custom TrackBar UserControl (VB.NET) - CodeProject

Re: Just wonderful


SSDiver2112 16-Jul-21 4:30

NuGet package
antaveiv 1-Feb-19 23:50

THANK YOU!
Member 13796594 29-May-18 6:17

Decimal values vs. Value Divisor....


Sam Marrocco 22-Jul-17 21:24

Change SliderShape while in movement


Pablo Jean 28-Mar-17 9:31

Silly Question
gianluca1 8-Dec-15 6:15

Up/Down Button
Member 11351552 1-Nov-15 6:44

Re: Up/Down Button


SSDiver2112 5-Nov-15 2:21

Greetings friend
abascalufe 7-May-15 15:01

changing brush color when slider


Axl-g 27-Apr-15 9:54

Re: changing brush color when slider


SSDiver2112 27-Apr-15 22:38

question about dll


Axl-g 16-Apr-15 11:45

Re: question about dll


SSDiver2112 16-Apr-15 19:09

Re: question about dll


Axl-g 17-Apr-15 3:24

Just thanks
Member 11593747 9-Apr-15 19:57

No Scroll Event?
Member 8607614 12-Mar-15 6:47

Re: No Scroll Event?


SSDiver2112 16-Mar-15 2:44

My vote of 1

https://www.codeproject.com/Articles/35104/gTrackBar-A-Custom-TrackBar-UserControl-VB-NET 12/13
06/10/2022, 16:25 gTrackBar - A Custom TrackBar UserControl (VB.NET) - CodeProject

Member 8890732 29-Sep-14 1:04

Re: My vote of 1
SSDiver2112 16-Mar-15 2:39

Range TrackBar
PDTPGY 31-Jul-14 19:46

Great!
Willy Kimura 26-Apr-14 14:54

My vote of 5
Mustapha Mahmoud 19-Mar-14 22:21

scroll event
Mustapha Mahmoud 14-Mar-14 9:24

Re: scroll event


SSDiver2112 17-Mar-14 9:17

Refresh 1 2 3 4 5 6 Next ᐅ

General News Suggestion Question Bug Answer Joke Praise Rant


Admin

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink Layout: fixed | fluid Article Copyright 2009 by SSDiver2112


Advertise Everything else Copyright ©
Privacy CodeProject, 1999-2022
Cookies
Terms of Use Web01 2.8:2022-09-22:1

https://www.codeproject.com/Articles/35104/gTrackBar-A-Custom-TrackBar-UserControl-VB-NET 13/13

You might also like