Hi everyone! I have been in the process of coding a replacement track bar which fits the color scheme and design of a program I am making. I would like some of the options to be controlled by properties which I can change in the designer. These include: whetether to show ticks, background color, pointer style/shape, maximum value, etc... The show ticks works fine, however I have tried multiple ways to get the Style field (which is an integer) to work, however everytime I change it, VB changes it back to its original value.
Here is my code:

Public Class myTrackBar
    Inherits Control
    Private MaxValue As Integer = 100
    Private Ticks As Integer = 20
    Private Pointer As New Bitmap(20, 40)
    Private Rect As New Rectangle(10, 10, 20, 40)
    Private Moving As Boolean
    Private Offset As Integer
    Private LOffset As Integer
    Private LastTick As Double
    Private TicksVisible As Boolean = False
    Private pColor As Color
    Private PointerStyle As Integer = 2

    Public Property Style As Integer
        Get
            Return PointerStyle
        End Get
        Set(value As Integer)
            PointerStyle = Style
            Invalidate(Rect)
        End Set
    End Property

    Public Property PointerColor As Color
    Public Property IsInt As Boolean

    Public Property ShowTicks As Boolean
        Get
            Return TicksVisible
        End Get
        Set(value As Boolean)
            TicksVisible = value
            MyBase.Refresh()
        End Set
    End Property

    Public Property Maximum As Integer
        Get
            Return MaxValue
        End Get
        Set(value As Integer)
            MaxValue = value
        End Set
    End Property

    Public Property Value As Double
        Get
            Dim tmpVal = Math.Min(Math.Max((Rect.X - (Rect.Width / 2)) * (MaxValue / (Width - (20 + Rect.Width / 2))), 0), MaxValue)
            If IsInt Then
                Return CInt(tmpVal)
            Else
                Return tmpVal
            End If
        End Get
        Set(ByVal value As Double)
            If value = 0 Then
                Rect.X = 10
            Else
                Rect.X = Math.Min(Math.Max(((value / MaxValue) * (Width - 20)) + 10, 10), Width - 20)
                Invalidate()
            End If
        End Set
    End Property

    Public Event Scroll(ByVal Sender As Object, ByVal e As ValueChangedEventArgs)
    'Public Event MouseDown As MouseEventHandler

    Public Sub New()
        Size = New Size(Me.Size)
        DoubleBuffered = True
    End Sub
    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        Dim br = New SolidBrush(BackColor)
        Dim brs = New SolidBrush(Color.LightGray)
        Dim p = New Pen(Color.Gray)
        e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.HighQuality

        Using g As Graphics = Graphics.FromImage(Pointer)
            g.Clear(Color.Transparent)
            Select Case PointerStyle
                Case 1
                    g.FillRectangle(brs, New Rectangle(0, 0, 10, 15))
                    g.FillPolygon(brs, New Point() {New Point(0, 15), New Point(5, 20), New Point(10, 15)})
                    g.DrawPolygon(p, New Point() {New Point(0, 0), New Point(0, 15), New Point(5, 20), New Point(10, 15), New Point(10, 0)})
                    LOffset = 8
                Case 2
                    g.FillRectangle(brs, New Rectangle(0, -5, 12, 30))
                    g.DrawRectangle(p, New Rectangle(0, -5, 12, 30))
                    LOffset = 10
                Case 3
                    g.FillEllipse(brs, New Rectangle(0, 0, 20, 20))
                    g.DrawEllipse(p, New Rectangle(0, 0, 20, 20))
                    LOffset = 8
                Case Else
                    g.FillRectangle(brs, New Rectangle(0, 0, 10, 15))
                    g.FillPolygon(brs, New Point() {New Point(0, 15), New Point(5, 20), New Point(10, 15)})
                    g.DrawPolygon(p, New Point() {New Point(0, 0), New Point(0, 15), New Point(5, 20), New Point(10, 15), New Point(10, 0)})
                    LOffset = 8
            End Select

        End Using

        e.Graphics.FillRectangle(br, New Rectangle(0, 0, Width, Height))
        e.Graphics.FillRectangle(Brushes.DarkGray, New Rectangle(20, Rect.Y + LOffset, Width - 40, 5))
        'Add ticks to control
        Dim X As Double = 15
        If TicksVisible Then
            For count As Integer = 1 To Ticks
                e.Graphics.DrawLine(Pens.White, New Point(X, 35), New Point(X, 40))
                X += (Width - 20) / Ticks
            Next
        End If
        LastTick = X - ((Width - 20) / Ticks)
        'Draw pointer graphic to control
        e.Graphics.DrawImage(Pointer, Rect)
    End Sub
    Protected Overrides Sub OnMouseDown(ByVal e As System.Windows.Forms.MouseEventArgs)
        If Rect.Contains(e.Location) Then
            Moving = True
            Offset = e.Location.X - Rect.X
        End If
        MyBase.OnMouseDown(e)
    End Sub
    Protected Overrides Sub OnMouseup(ByVal e As System.Windows.Forms.MouseEventArgs)
        Moving = False
        MyBase.OnMouseUp(e)
    End Sub
    Protected Overrides Sub OnMouseMove(ByVal e As System.Windows.Forms.MouseEventArgs)
        If Moving Then
            Rect.X = Math.Min(Math.Max(e.Location.X - Offset, 10), Width - 20)
            'Rect.X = Width - 15
            RaiseEvent Scroll(Me, New ValueChangedEventArgs(Rect.X))
            Invalidate()
        End If
    End Sub
End Class
Public Class ValueChangedEventArgs
    Inherits EventArgs
    Public Property Value As Integer
    Public Sub New(ByVal Value As Integer)
        Me.Value = Value
    End Sub
End Class

This code is not entierly complete, so don't fuss about the details (unless there are some major problems). Any help would be greatly appreciated. Thanks

HI the code where you set the style value is wrong...

  Public Property Style As Integer
16.        Get
17.            Return PointerStyle
18.        End Get
19.        Set(value As Integer)
20.            PointerStyle = Style
21.            Invalidate(Rect)
22.        End Set
23.    End Property

You want PointerStyle = value not PointerStyle = Style you are constantly resetting your style value to the initial value.

Oops, stupid mistake, it works fine now. Thanks! On the same topic, I have a control collection in my form which fills up to the point where a scroll bar appears. Is there a way to either override the standard Microsoft draw method for just the scroll bar or to create a custom scroll bar which can then control the scroll of the control collection?

This article has been dead for over six months. Start a new discussion instead.