Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Question
Monday, February 9, 2015 5:12 PM
I'm suing VB 2010 Express and I need to create a trackbar control with double trackbars.
I can't find "Doubletrackbar" control from Toolbox. I searched online and found one post toking about it (http://www.vbforums.com/showthread.php?620394-WIP-Double-TrackBar). Unfortunately, I can't use the code in the post. Anyone can help?
Thank you very much.
All replies (29)
Wednesday, February 11, 2015 12:01 AM ✅Answered | 1 vote
Hi,
Well, unfortunately you are going to have to leave the Minimum and the ValueLeft set to 0 and build it that way. Then after you build it and add one to the form you can set the ValueLeft to the value you want in the Properties on the [Design] tab, i set it to 80 in the example below. Do Not change the Minimum property from 0 or it screws up and does not draw the thumb buttons correctly.
You will have to keep the range from 0 to 300 and just do the calculations you want in the forms code by adding 100 to each of the ValueLeft and ValueRight properties and then divide that by 100. That will give you the values 1.00 to 4.00. Below is the code i used in the form to calculate the values and display them.
Like i said before, this control was poorly designed and was never completed. Unless it is pretty much completely rebuilt, it is just not going to have very reliable results or predictable behavior.
Public Class Form1
Private Lval As Double
Private Rval As Double
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Lval = (DoubleTrackBar1.ValueLeft + 100) / 100
Rval = (DoubleTrackBar1.ValueRight + 100) / 100
Label1.Text = "Left = " & Lval.ToString
Label2.Text = "Right = " & Rval.ToString
End Sub
Private Sub DoubleTrackBar1_LeftValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles DoubleTrackBar1.LeftValueChanged
Lval = (DoubleTrackBar1.ValueLeft + 100) / 100
Label1.Text = "Left = " & Lval.ToString
End Sub
Private Sub DoubleTrackBar1_RightValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles DoubleTrackBar1.RightValueChanged
Rval = (DoubleTrackBar1.ValueRight + 100) / 100
Label2.Text = "Right = " & Rval.ToString
End Sub
End Class
If you say it can`t be done then i`ll try it
Wednesday, February 11, 2015 12:30 AM ✅Answered
Thank you very much, IronRazerz.
I'll do as you suggested.
Monday, February 9, 2015 6:51 PM
Suing or using?
La vida loca
Monday, February 9, 2015 7:09 PM
So, what is the problem you are having with using the control from that link? Is there something it does not do that you need to do?
If you say it can`t be done then i`ll try it
Monday, February 9, 2015 7:22 PM
I'm suing VB 2010 Express and I need to create a trackbar control with double trackbars.
I can't find "Doubletrackbar" control from Toolbox. I searched online and found one post toking about it (http://www.vbforums.com/showthread.php?620394-WIP-Double-TrackBar). Unfortunately, I can't use the code in the post. Anyone can help?
Thank you very much.
I think you mean a "Range Control", not a doubletrackbar:
If you can't work one for yourself or from something you find, you might want to consider third-party stuff like the one I showed which is from DevExpress.
Still lost in code, just at a little higher level.
:-)
Monday, February 9, 2015 10:14 PM
sorry, it's "using".
Monday, February 9, 2015 10:25 PM
I downloaded the code from the link but I can't get it to run in Visual Basic Express 2010. It creates many errors when I compile it. I don't know how to link it to the form.
I can only find "Trackbar" from Toobox. I can't find anything like "Double Trackbar".
Below is the code from the link.
Public Class DoubleTrackBar
Inherits Control
Public Sub New()
Me.DoubleBuffered = True
Me.SetDefaults()
End Sub
Private Sub SetDefaults()
Me.Orientation = Windows.Forms.Orientation.Horizontal
Me.SmallChange = 1
Me.Maximum = 10
Me.Minimum = 0
Me.ValueLeft = 0
Me.ValueRight = 7
End Sub
#Region " Private Fields "
Private leftThumbState As VisualStyles.TrackBarThumbState
Private rightThumbState As VisualStyles.TrackBarThumbState
Private draggingLeft, draggingRight As Boolean
#End Region
#Region " Enums "
Public Enum Thumbs
None = 0
Left = 1
Right = 2
End Enum
#End Region
#Region " Properties "
Private _SelectedThumb As Thumbs
''' <summary>
''' Gets the thumb that had focus last.
''' </summary>
''' <returns>The thumb that had focus last.</returns>
<Description("The thumb that had focus last.")> _
Public Property SelectedThumb() As Thumbs
Get
Return _SelectedThumb
End Get
Private Set(value As Thumbs)
_SelectedThumb = value
End Set
End Property
Private _ValueLeft As Integer
''' <summary>
''' Gets or sets the position of the left slider.
''' </summary>
''' <returns>The position of the left slider.</returns>
<Description("The position of the left slider.")> _
Public Property ValueLeft() As Integer
Get
Return _ValueLeft
End Get
Set(ByVal value As Integer)
If value < Me.Minimum OrElse value > Me.Maximum Then
Throw New ArgumentException(String.Format("Value of '{0}' is not valid for 'ValueLeft'. 'ValueLeft' should be between 'Minimum' and 'Maximum'.", value.ToString()), "ValueLeft")
End If
If value > Me.ValueRight Then
Throw New ArgumentException(String.Format("Value of '{0}' is not valid for 'ValueLeft'. 'ValueLeft' should be less than or equal to 'ValueRight'.", value.ToString()), "ValueLeft")
End If
_ValueLeft = value
Me.OnValueChanged(EventArgs.Empty)
Me.OnLeftValueChanged(EventArgs.Empty)
Me.Invalidate()
End Set
End Property
Private _ValueRight As Integer
''' <summary>
''' Gets or sets the position of the right slider.
''' </summary>
''' <returns>The position of the right slider.</returns>
<Description("The position of the right slider.")> _
Public Property ValueRight() As Integer
Get
Return _ValueRight
End Get
Set(ByVal value As Integer)
If value < Me.Minimum OrElse value > Me.Maximum Then
Throw New ArgumentException(String.Format("Value of '{0}' is not valid for 'ValueRight'. 'ValueRight' should be between 'Minimum' and 'Maximum'.", value.ToString()), "ValueRight")
End If
If value < Me.ValueLeft Then
Throw New ArgumentException(String.Format("Value of '{0}' is not valid for 'ValueRight'. 'ValueRight' should be greater than or equal to 'ValueLeft'.", value.ToString()), "ValueLeft")
End If
_ValueRight = value
Me.OnValueChanged(EventArgs.Empty)
Me.OnRightValueChanged(EventArgs.Empty)
Me.Invalidate()
End Set
End Property
Private _Minimum As Integer
''' <summary>
''' Gets or sets the minimum value.
''' </summary>
''' <returns>The minimum value.</returns>
<Description("The minimum value.")> _
Public Property Minimum() As Integer
Get
Return _Minimum
End Get
Set(ByVal value As Integer)
If value >= Me.Maximum Then
Throw New ArgumentException(String.Format("Value of '{0}' is not valid for 'Minimum'. 'Minimum' should be less than 'Maximum'.", value.ToString()), "Minimum")
End If
_Minimum = value
Me.Invalidate()
End Set
End Property
Private _Maximum As Integer
''' <summary>
''' Gets or sets the maximum value.
''' </summary>
''' <returns>The maximum value.</returns>
<Description("The maximum value.")> _
Public Property Maximum() As Integer
Get
Return _Maximum
End Get
Set(ByVal value As Integer)
If value <= Me.Minimum Then
Throw New ArgumentException(String.Format("Value of '{0}' is not valid for 'Maximum'. 'Maximum' should be greater than 'Minimum'.", value.ToString()), "Maximum")
End If
_Maximum = value
Me.Invalidate()
End Set
End Property
Private _Orientation As Orientation
''' <summary>
''' Gets or sets the orientation of the control.
''' </summary>
''' <returns>The orientation of the control.</returns>
<Description("The orientation of the control.")> _
Public Property Orientation() As Orientation
Get
Return _Orientation
End Get
Set(ByVal value As Orientation)
_Orientation = value
End Set
End Property
Private _SmallChange As Integer
''' <summary>
''' Gets or sets the amount of positions the closest slider moves when the control is clicked.
''' </summary>
''' <returns>The amount of positions the closest slider moves when the control is clicked.</returns>
<Description("The amount of positions the closest slider moves when the control is clicked.")> _
Public Property SmallChange() As Integer
Get
Return _SmallChange
End Get
Set(ByVal value As Integer)
_SmallChange = value
End Set
End Property
Private ReadOnly Property RelativeValueLeft As Double
Get
Dim diff = Me.Maximum - Me.Minimum
Return If(diff = 0, Me.ValueLeft, Me.ValueLeft / diff)
End Get
End Property
Private ReadOnly Property RelativeValueRight As Double
Get
Dim diff = Me.Maximum - Me.Minimum
Return If(diff = 0, Me.ValueLeft, Me.ValueRight / diff)
End Get
End Property
#End Region
#Region " Methods "
Public Sub IncrementLeft()
Dim newValue = Math.Min(Me.ValueLeft + 1, Me.Maximum)
If Me.IsValidValueLeft(newValue) Then
Me.ValueLeft = newValue
End If
Me.Invalidate()
End Sub
Public Sub IncrementRight()
Dim newValue = Math.Min(Me.ValueRight + 1, Me.Maximum)
If Me.IsValidValueRight(newValue) Then
Me.ValueRight = newValue
End If
Me.Invalidate()
End Sub
Public Sub DecrementLeft()
Dim newValue = Math.Max(Me.ValueLeft - 1, Me.Minimum)
If Me.IsValidValueLeft(newValue) Then
Me.ValueLeft = newValue
End If
Me.Invalidate()
End Sub
Public Sub DecrementRight()
Dim newValue = Math.Max(Me.ValueRight - 1, Me.Minimum)
If Me.IsValidValueRight(newValue) Then
Me.ValueRight = newValue
End If
Me.Invalidate()
End Sub
Private Function IsValidValueLeft(ByVal value As Integer) As Boolean
Return (value >= Me.Minimum AndAlso value <= Me.Maximum AndAlso value < Me.ValueRight)
End Function
Private Function IsValidValueRight(ByVal value As Integer) As Boolean
Return (value >= Me.Minimum AndAlso value <= Me.Maximum AndAlso value > Me.ValueLeft)
End Function
Private Function GetLeftThumbRectangle(Optional ByVal g As Graphics = Nothing) As Rectangle
Dim shouldDispose = (g Is Nothing)
If shouldDispose Then g = Me.CreateGraphics()
Dim rect = Me.GetThumbRectangle(Me.RelativeValueLeft, g)
If shouldDispose Then g.Dispose()
Return rect
End Function
Private Function GetRightThumbRectangle(Optional ByVal g As Graphics = Nothing) As Rectangle
Dim shouldDispose = (g Is Nothing)
If shouldDispose Then g = Me.CreateGraphics()
Dim rect = Me.GetThumbRectangle(Me.RelativeValueRight, g)
If shouldDispose Then g.Dispose()
Return rect
End Function
Private Function GetThumbRectangle(ByVal relativeValue As Double, ByVal g As Graphics) As Rectangle
Dim size = TrackBarRenderer.GetBottomPointingThumbSize(g, VisualStyles.TrackBarThumbState.Normal)
Dim border = CInt(size.Width / 2)
Dim w = Me.GetTrackRectangle(border).Width
Dim x = CInt(Math.Abs(Me.Minimum) / (Me.Maximum - Me.Minimum) * w + relativeValue * w)
Dim y = CInt((Me.Height - size.Height) / 2)
Return New Rectangle(New Point(x, y), size)
End Function
Private Function GetTrackRectangle(ByVal border As Integer) As Rectangle
'TODO: Select Case for hor/ver
Return New Rectangle(border, CInt(Me.Height / 2) - 3, Me.Width - 2 * border - 1, 4)
End Function
Private Function GetClosestSlider(ByVal point As Point) As Thumbs
Dim leftThumbRect = Me.GetLeftThumbRectangle()
Dim rightThumbRect = Me.GetRightThumbRectangle()
If Me.Orientation = Windows.Forms.Orientation.Horizontal Then
If Math.Abs(leftThumbRect.X - point.X) > Math.Abs(rightThumbRect.X - point.X) _
AndAlso Math.Abs(leftThumbRect.Right - point.X) > Math.Abs(rightThumbRect.Right - point.X) Then
Return Thumbs.Right
Else
Return Thumbs.Left
End If
Else
If Math.Abs(leftThumbRect.Y - point.Y) > Math.Abs(rightThumbRect.Y - point.Y) _
AndAlso Math.Abs(leftThumbRect.Bottom - point.Y) > Math.Abs(rightThumbRect.Bottom - point.Y) Then
Return Thumbs.Right
Else
Return Thumbs.Left
End If
End If
End Function
Private Sub SetThumbState(ByVal location As Point, ByVal newState As VisualStyles.TrackBarThumbState)
Dim leftThumbRect = Me.GetLeftThumbRectangle()
Dim rightThumbRect = Me.GetRightThumbRectangle()
If leftThumbRect.Contains(location) Then
leftThumbState = newState
Else
If Me.SelectedThumb = Thumbs.Left Then
leftThumbState = VisualStyles.TrackBarThumbState.Hot
Else
leftThumbState = VisualStyles.TrackBarThumbState.Normal
End If
End If
If rightThumbRect.Contains(location) Then
rightThumbState = newState
Else
If Me.SelectedThumb = Thumbs.Right Then
rightThumbState = VisualStyles.TrackBarThumbState.Hot
Else
rightThumbState = VisualStyles.TrackBarThumbState.Normal
End If
End If
End Sub
Protected Overrides Sub OnMouseMove(ByVal e As System.Windows.Forms.MouseEventArgs)
MyBase.OnMouseMove(e)
Me.SetThumbState(e.Location, VisualStyles.TrackBarThumbState.Hot)
Dim offset = CInt(e.Location.X / (Me.Width) * (Me.Maximum - Me.Minimum))
Dim newValue = Me.Minimum + offset
If draggingLeft Then
If Me.IsValidValueLeft(newValue) Then Me.ValueLeft = newValue
ElseIf draggingRight Then
If Me.IsValidValueRight(newValue) Then Me.ValueRight = newValue
End If
Me.Invalidate()
End Sub
Protected Overrides Sub OnMouseDown(ByVal e As System.Windows.Forms.MouseEventArgs)
MyBase.OnMouseDown(e)
Me.Focus()
Me.SetThumbState(e.Location, VisualStyles.TrackBarThumbState.Pressed)
draggingLeft = (leftThumbState = VisualStyles.TrackBarThumbState.Pressed)
If Not draggingLeft Then draggingRight = (rightThumbState = VisualStyles.TrackBarThumbState.Pressed)
If draggingLeft Then
Me.SelectedThumb = Thumbs.Left
ElseIf draggingRight Then
Me.SelectedThumb = Thumbs.Right
End If
If Not draggingLeft AndAlso Not draggingRight Then
If Me.GetClosestSlider(e.Location) = 1 Then
If e.X < Me.GetLeftThumbRectangle().X Then
Me.DecrementLeft()
Else
Me.IncrementLeft()
End If
Me.SelectedThumb = Thumbs.Left
Else
If e.X < Me.GetRightThumbRectangle().X Then
Me.DecrementRight()
Else
Me.IncrementRight()
End If
Me.SelectedThumb = Thumbs.Right
End If
End If
Me.Invalidate()
End Sub
Protected Overrides Sub OnMouseUp(ByVal e As System.Windows.Forms.MouseEventArgs)
MyBase.OnMouseUp(e)
draggingLeft = False
draggingRight = False
Me.Invalidate()
End Sub
Protected Overrides Sub OnMouseWheel(e As System.Windows.Forms.MouseEventArgs)
MyBase.OnMouseWheel(e)
If e.Delta = 0 Then Return
If Me.SelectedThumb = 1 Then
If e.Delta > 0 Then
Me.IncrementLeft()
Else
Me.DecrementLeft()
End If
ElseIf Me.SelectedThumb = 2 Then
If e.Delta > 0 Then
Me.IncrementRight()
Else
Me.DecrementRight()
End If
End If
End Sub
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
MyBase.OnPaint(e)
Dim thumbSize = Me.GetThumbRectangle(0, e.Graphics).Size
Dim trackRect = Me.GetTrackRectangle(CInt(thumbSize.Width / 2))
Dim ticksRect = trackRect : ticksRect.Offset(0, 15)
TrackBarRenderer.DrawVerticalTrack(e.Graphics, trackRect)
TrackBarRenderer.DrawHorizontalTicks(e.Graphics, ticksRect, Me.Maximum - Me.Minimum + 1, VisualStyles.EdgeStyle.Etched)
TrackBarRenderer.DrawBottomPointingThumb(e.Graphics, Me.GetLeftThumbRectangle(e.Graphics), leftThumbState)
TrackBarRenderer.DrawBottomPointingThumb(e.Graphics, Me.GetRightThumbRectangle(e.Graphics), rightThumbState)
End Sub
#End Region
#Region " Events "
Public Event ValueChanged As EventHandler
Public Event LeftValueChanged As EventHandler
Public Event RightValueChanged As EventHandler
Protected Overridable Sub OnValueChanged(e As EventArgs)
RaiseEvent ValueChanged(Me, e)
End Sub
Protected Overridable Sub OnLeftValueChanged(e As EventArgs)
RaiseEvent LeftValueChanged(Me, e)
End Sub
Protected Overridable Sub OnRightValueChanged(e As EventArgs)
RaiseEvent RightValueChanged(Me, e)
End Sub
#End Region
End Class
Monday, February 9, 2015 10:54 PM | 2 votes
Hi,
Whoever made it did not have Option Strict turned on and there was also a namespace that was not imported. I just went through the code and fixed all the errors and added the namespace. It seems to be working after that.
Open your project or even a new form project just to test it on. When the project is opened go to the VB Menu and click (Project) and then select (Add Class). You can leave it named as the default name "Class1.vb" if you want. When the empty class code opens, copy and paste the fixed code below in replacing the 2 lines of code that are generated automatically. Save the project.
Then go to the VB Menu and click (Build) and select (Build YourProjectsName). After it is finished building you can go to the Forms [Design] tab and you will find the DoubleTrackBar control in the top of your toolbox. 8)
Imports System.ComponentModel
Public Class DoubleTrackBar
Inherits Control
Public Sub New()
Me.DoubleBuffered = True
Me.SetDefaults()
End Sub
Private Sub SetDefaults()
'Added these to set to a decent size when a new one is added to the form
Me.Width = 200
Me.Height = 50
Me.Orientation = Orientation.Horizontal
Me.SmallChange = 1
Me.Maximum = 400
Me.Minimum = 0
Me.ValueLeft = 0
Me.ValueRight = 300
End Sub
#Region " Private Fields "
Private leftThumbState As VisualStyles.TrackBarThumbState
Private rightThumbState As VisualStyles.TrackBarThumbState
Private draggingLeft, draggingRight As Boolean
#End Region
#Region " Enums "
Public Enum Thumbs
None = 0
Left = 1
Right = 2
End Enum
#End Region
#Region " Properties "
Private _SelectedThumb As Thumbs
''' <summary>
''' Gets the thumb that had focus last.
''' </summary>
''' <returns>The thumb that had focus last.</returns>
<Description("The thumb that had focus last.")> _
Public Property SelectedThumb() As Thumbs
Get
Return _SelectedThumb
End Get
Private Set(ByVal value As Thumbs)
_SelectedThumb = value
End Set
End Property
Private _ValueLeft As Integer
''' <summary>
''' Gets or sets the position of the left slider.
''' </summary>
''' <returns>The position of the left slider.</returns>
<Description("The position of the left slider.")> _
Public Property ValueLeft() As Integer
Get
Return _ValueLeft
End Get
Set(ByVal value As Integer)
If value < Me.Minimum OrElse value > Me.Maximum Then
Throw New ArgumentException(String.Format("Value of '{0}' is not valid for 'ValueLeft'. 'ValueLeft' should be between 'Minimum' and 'Maximum'.", value.ToString()), "ValueLeft")
End If
If value > Me.ValueRight Then
Throw New ArgumentException(String.Format("Value of '{0}' is not valid for 'ValueLeft'. 'ValueLeft' should be less than or equal to 'ValueRight'.", value.ToString()), "ValueLeft")
End If
_ValueLeft = value
Me.OnValueChanged(EventArgs.Empty)
Me.OnLeftValueChanged(EventArgs.Empty)
Me.Invalidate()
End Set
End Property
Private _ValueRight As Integer
''' <summary>
''' Gets or sets the position of the right slider.
''' </summary>
''' <returns>The position of the right slider.</returns>
<Description("The position of the right slider.")> _
Public Property ValueRight() As Integer
Get
Return _ValueRight
End Get
Set(ByVal value As Integer)
If value < Me.Minimum OrElse value > Me.Maximum Then
Throw New ArgumentException(String.Format("Value of '{0}' is not valid for 'ValueRight'. 'ValueRight' should be between 'Minimum' and 'Maximum'.", value.ToString()), "ValueRight")
End If
If value < Me.ValueLeft Then
Throw New ArgumentException(String.Format("Value of '{0}' is not valid for 'ValueRight'. 'ValueRight' should be greater than or equal to 'ValueLeft'.", value.ToString()), "ValueLeft")
End If
_ValueRight = value
Me.OnValueChanged(EventArgs.Empty)
Me.OnRightValueChanged(EventArgs.Empty)
Me.Invalidate()
End Set
End Property
Private _Minimum As Integer
''' <summary>
''' Gets or sets the minimum value.
''' </summary>
''' <returns>The minimum value.</returns>
<Description("The minimum value.")> _
Public Property Minimum() As Integer
Get
Return _Minimum
End Get
Set(ByVal value As Integer)
If value >= Me.Maximum Then
Throw New ArgumentException(String.Format("Value of '{0}' is not valid for 'Minimum'. 'Minimum' should be less than 'Maximum'.", value.ToString()), "Minimum")
End If
_Minimum = value
Me.Invalidate()
End Set
End Property
Private _Maximum As Integer
''' <summary>
''' Gets or sets the maximum value.
''' </summary>
''' <returns>The maximum value.</returns>
<Description("The maximum value.")> _
Public Property Maximum() As Integer
Get
Return _Maximum
End Get
Set(ByVal value As Integer)
If value <= Me.Minimum Then
Throw New ArgumentException(String.Format("Value of '{0}' is not valid for 'Maximum'. 'Maximum' should be greater than 'Minimum'.", value.ToString()), "Maximum")
End If
_Maximum = value
Me.Invalidate()
End Set
End Property
Private _Orientation As Orientation
''' <summary>
''' Gets or sets the orientation of the control.
''' </summary>
''' <returns>The orientation of the control.</returns>
<Description("The orientation of the control.")> _
Public Property Orientation() As Orientation
Get
Return _Orientation
End Get
Set(ByVal value As Orientation)
_Orientation = value
End Set
End Property
Private _SmallChange As Integer
''' <summary>
''' Gets or sets the amount of positions the closest slider moves when the control is clicked.
''' </summary>
''' <returns>The amount of positions the closest slider moves when the control is clicked.</returns>
<Description("The amount of positions the closest slider moves when the control is clicked.")> _
Public Property SmallChange() As Integer
Get
Return _SmallChange
End Get
Set(ByVal value As Integer)
_SmallChange = value
End Set
End Property
Private ReadOnly Property RelativeValueLeft() As Double
Get
Dim diff As Double = Me.Maximum - Me.Minimum
Return If(diff = 0, Me.ValueLeft, Me.ValueLeft / diff)
End Get
End Property
Private ReadOnly Property RelativeValueRight() As Double
Get
Dim diff As Double = Me.Maximum - Me.Minimum
Return If(diff = 0, Me.ValueLeft, Me.ValueRight / diff)
End Get
End Property
#End Region
#Region " Methods "
Public Sub IncrementLeft()
Dim newValue As Integer = Math.Min(Me.ValueLeft + 1, Me.Maximum)
If Me.IsValidValueLeft(newValue) Then
Me.ValueLeft = newValue
End If
Me.Invalidate()
End Sub
Public Sub IncrementRight()
Dim newValue As Integer = Math.Min(Me.ValueRight + 1, Me.Maximum)
If Me.IsValidValueRight(newValue) Then
Me.ValueRight = newValue
End If
Me.Invalidate()
End Sub
Public Sub DecrementLeft()
Dim newValue As Integer = Math.Max(Me.ValueLeft - 1, Me.Minimum)
If Me.IsValidValueLeft(newValue) Then
Me.ValueLeft = newValue
End If
Me.Invalidate()
End Sub
Public Sub DecrementRight()
Dim newValue As Integer = Math.Max(Me.ValueRight - 1, Me.Minimum)
If Me.IsValidValueRight(newValue) Then
Me.ValueRight = newValue
End If
Me.Invalidate()
End Sub
Private Function IsValidValueLeft(ByVal value As Integer) As Boolean
Return (value >= Me.Minimum AndAlso value <= Me.Maximum AndAlso value < Me.ValueRight)
End Function
Private Function IsValidValueRight(ByVal value As Integer) As Boolean
Return (value >= Me.Minimum AndAlso value <= Me.Maximum AndAlso value > Me.ValueLeft)
End Function
Private Function GetLeftThumbRectangle(Optional ByVal g As Graphics = Nothing) As Rectangle
Dim shouldDispose As Boolean = (g Is Nothing)
If shouldDispose Then g = Me.CreateGraphics()
Dim rect As Rectangle = Me.GetThumbRectangle(Me.RelativeValueLeft, g)
If shouldDispose Then g.Dispose()
Return rect
End Function
Private Function GetRightThumbRectangle(Optional ByVal g As Graphics = Nothing) As Rectangle
Dim shouldDispose As Boolean = (g Is Nothing)
If shouldDispose Then g = Me.CreateGraphics()
Dim rect As Rectangle = Me.GetThumbRectangle(Me.RelativeValueRight, g)
If shouldDispose Then g.Dispose()
Return rect
End Function
Private Function GetThumbRectangle(ByVal relativeValue As Double, ByVal g As Graphics) As Rectangle
Dim size As Size = TrackBarRenderer.GetBottomPointingThumbSize(g, VisualStyles.TrackBarThumbState.Normal)
Dim border As Integer = CInt(size.Width / 2)
Dim w As Integer = Me.GetTrackRectangle(border).Width
Dim x As Integer = CInt(Math.Abs(Me.Minimum) / (Me.Maximum - Me.Minimum) * w + relativeValue * w)
Dim y As Integer = CInt((Me.Height - size.Height) / 2)
Return New Rectangle(New Point(x, y), size)
End Function
Private Function GetTrackRectangle(ByVal border As Integer) As Rectangle
'TODO: Select Case for hor/ver
Return New Rectangle(border, CInt(Me.Height / 2) - 3, Me.Width - 2 * border - 1, 4)
End Function
Private Function GetClosestSlider(ByVal point As Point) As Thumbs
Dim leftThumbRect As Rectangle = Me.GetLeftThumbRectangle()
Dim rightThumbRect As Rectangle = Me.GetRightThumbRectangle()
If Me.Orientation = Windows.Forms.Orientation.Horizontal Then
If Math.Abs(leftThumbRect.X - point.X) > Math.Abs(rightThumbRect.X - point.X) _
AndAlso Math.Abs(leftThumbRect.Right - point.X) > Math.Abs(rightThumbRect.Right - point.X) Then
Return Thumbs.Right
Else
Return Thumbs.Left
End If
Else
If Math.Abs(leftThumbRect.Y - point.Y) > Math.Abs(rightThumbRect.Y - point.Y) _
AndAlso Math.Abs(leftThumbRect.Bottom - point.Y) > Math.Abs(rightThumbRect.Bottom - point.Y) Then
Return Thumbs.Right
Else
Return Thumbs.Left
End If
End If
End Function
Private Sub SetThumbState(ByVal location As Point, ByVal newState As VisualStyles.TrackBarThumbState)
Dim leftThumbRect As Rectangle = Me.GetLeftThumbRectangle()
Dim rightThumbRect As Rectangle = Me.GetRightThumbRectangle()
If leftThumbRect.Contains(location) Then
leftThumbState = newState
Else
If Me.SelectedThumb = Thumbs.Left Then
leftThumbState = VisualStyles.TrackBarThumbState.Hot
Else
leftThumbState = VisualStyles.TrackBarThumbState.Normal
End If
End If
If rightThumbRect.Contains(location) Then
rightThumbState = newState
Else
If Me.SelectedThumb = Thumbs.Right Then
rightThumbState = VisualStyles.TrackBarThumbState.Hot
Else
rightThumbState = VisualStyles.TrackBarThumbState.Normal
End If
End If
End Sub
Protected Overrides Sub OnMouseMove(ByVal e As System.Windows.Forms.MouseEventArgs)
MyBase.OnMouseMove(e)
Me.SetThumbState(e.Location, VisualStyles.TrackBarThumbState.Hot)
Dim offset As Integer = CInt(e.Location.X / (Me.Width) * (Me.Maximum - Me.Minimum))
Dim newValue As Integer = Me.Minimum + offset
If draggingLeft Then
If Me.IsValidValueLeft(newValue) Then Me.ValueLeft = newValue
ElseIf draggingRight Then
If Me.IsValidValueRight(newValue) Then Me.ValueRight = newValue
End If
Me.Invalidate()
End Sub
Protected Overrides Sub OnMouseDown(ByVal e As System.Windows.Forms.MouseEventArgs)
MyBase.OnMouseDown(e)
Me.Focus()
Me.SetThumbState(e.Location, VisualStyles.TrackBarThumbState.Pressed)
draggingLeft = (leftThumbState = VisualStyles.TrackBarThumbState.Pressed)
If Not draggingLeft Then draggingRight = (rightThumbState = VisualStyles.TrackBarThumbState.Pressed)
If draggingLeft Then
Me.SelectedThumb = Thumbs.Left
ElseIf draggingRight Then
Me.SelectedThumb = Thumbs.Right
End If
If Not draggingLeft AndAlso Not draggingRight Then
If Me.GetClosestSlider(e.Location) = 1 Then
If e.X < Me.GetLeftThumbRectangle().X Then
Me.DecrementLeft()
Else
Me.IncrementLeft()
End If
Me.SelectedThumb = Thumbs.Left
Else
If e.X < Me.GetRightThumbRectangle().X Then
Me.DecrementRight()
Else
Me.IncrementRight()
End If
Me.SelectedThumb = Thumbs.Right
End If
End If
Me.Invalidate()
End Sub
Protected Overrides Sub OnMouseUp(ByVal e As System.Windows.Forms.MouseEventArgs)
MyBase.OnMouseUp(e)
draggingLeft = False
draggingRight = False
Me.Invalidate()
End Sub
Protected Overrides Sub OnMouseWheel(ByVal e As System.Windows.Forms.MouseEventArgs)
MyBase.OnMouseWheel(e)
If e.Delta = 0 Then Return
If Me.SelectedThumb = 1 Then
If e.Delta > 0 Then
Me.IncrementLeft()
Else
Me.DecrementLeft()
End If
ElseIf Me.SelectedThumb = 2 Then
If e.Delta > 0 Then
Me.IncrementRight()
Else
Me.DecrementRight()
End If
End If
End Sub
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
MyBase.OnPaint(e)
Dim thumbSize As Size = Me.GetThumbRectangle(0, e.Graphics).Size
Dim trackRect As Rectangle = Me.GetTrackRectangle(CInt(thumbSize.Width / 2))
Dim ticksRect As Rectangle = trackRect
ticksRect.Offset(0, -15) 'changed to -15 to place ticks at the top
'added this to keep ticks at a decent spacing
Dim tickspacing As Integer = CInt((Me.Maximum - Me.Minimum) / 10) + 1
TrackBarRenderer.DrawHorizontalTrack(e.Graphics, trackRect)
TrackBarRenderer.DrawHorizontalTicks(e.Graphics, ticksRect, tickspacing, VisualStyles.EdgeStyle.Etched)
'Changed these to draw the top pointing thumb button
TrackBarRenderer.DrawTopPointingThumb(e.Graphics, Me.GetLeftThumbRectangle(e.Graphics), leftThumbState)
TrackBarRenderer.DrawTopPointingThumb(e.Graphics, Me.GetRightThumbRectangle(e.Graphics), rightThumbState)
End Sub
#End Region
#Region " Events "
Public Event ValueChanged As EventHandler
Public Event LeftValueChanged As EventHandler
Public Event RightValueChanged As EventHandler
Protected Overridable Sub OnValueChanged(ByVal e As EventArgs)
RaiseEvent ValueChanged(Me, e)
End Sub
Protected Overridable Sub OnLeftValueChanged(ByVal e As EventArgs)
RaiseEvent LeftValueChanged(Me, e)
End Sub
Protected Overridable Sub OnRightValueChanged(ByVal e As EventArgs)
RaiseEvent RightValueChanged(Me, e)
End Sub
#End Region
End Class
If you say it can`t be done then i`ll try it
Tuesday, February 10, 2015 12:12 AM
Thank you so much. It works now. I do have some more problems. 1. when I add the DoubleTrackBar to form, the code generated in Form1.Designer.vb shows as Me.DoubleTrackBar1 = New DoubleTrackBar.DoubleTrackBar() Then error msg shows as Type 'DoubleTrackBar.DoubleTrackBar' is not defined. when I change it to Me.DoubleTrackBar1 = New DoubleTrackBar() The compile goes through. However, when I another control, say Textbox, it changed to Me.DoubleTrackBar1 = New DoubleTrackBar.DoubleTrackBar() again in Form1.Designer.vb. 2.I want to add "Tick" on it. I can't find the option. How should I do it? Thank you very much. Fred
Tuesday, February 10, 2015 1:23 AM
Hi,
Did you name your project "DoubleTrackBar" ? In the Form.Designer.vb file it should be in this format.
testing_doubletrackbar__msdn_ is the Namespace of my application.
DoubleTrackBar is the name of the DoubleTrackBar class.
Me.DoubleTrackBar1 = New testing_doubletrackbar__msdn_.DoubleTrackBar
Look in your application`s properties and see if DoubleTrackBar is your applications namespace name. If it is then maybe try it in another test application and name the project something other than DoubleTrackbar Naming the project the same as the class does not seem like it would mess it up though.
Also, at the end of the Form.Designer.vb file it should also be declaring the new instance of it like this. Of coarse your namespace will be names different than mine though.
Friend WithEvents DoubleTrackBar1 As testing_doubletrackbar__msdn_.DoubleTrackBar
I am using VS2008 targeting .Net 3.5 so, maybe someone that has a newer VS version targeting .Net 4.0 or 4.5 will test it and see if they are having these problems. It seems to working fine on my end.
To show the Ticks you will need to resize the height of the DoubleTrackBar. They are there but, not showing until you make the height taller.
If you say it can`t be done then i`ll try it
Tuesday, February 10, 2015 3:08 AM | 1 vote
Works fine in Visual Studio 2015 Preview compiled to both .Net 4.0 and 4.6 preview (4.5.3) except in 4.6 preview the lines with this
Windows.Forms.Orientation.Horizontal
had to be changed to just this for some reason
Orientation.Horizontal
La vida loca
Tuesday, February 10, 2015 3:31 AM | 1 vote
@ Mr. Monkeyboy,
Thanks for testing it. I was not sure if it was my system or not. There`s another one to add to the collection. 8)
I started making a new class before OP replied back that i am hoping to maybe incorporate all the functions of a TrackBar into plus a few others needed for the 2nd thumb. I have the basic operations working and looking like a standard Trackbar right now but, have quite a ways to go on it still.
If you say it can`t be done then i`ll try it
Tuesday, February 10, 2015 4:18 AM
@ Mr. Monkeyboy,
Thanks for testing it. I was not sure if it was my system or not. There`s another one to add to the collection. 8)
I started making a new class before OP replied back that i am hoping to maybe incorporate all the functions of a TrackBar into plus a few others needed for the 2nd thumb. I have the basic operations working and looking like a standard Trackbar right now but, have quite a ways to go on it still.
If you say it can`t be done then i`ll try it
Awesome. I set that TrackBar to vertical but it didn't work like the original one will do. Plus the original one can be made to show tick marks in different ways. When you get done I'll test it in VS 2015 Preview if you'd like.
La vida loca
Tuesday, February 10, 2015 4:58 PM
Thank you very much.
Yes, it works after my created a new project named "TestDoubleTrackBar". It seems that there is some problem if the project name is the same as class name.
I do have some new issues. What I want to do is to set the range to (100, 400). I then divide the left and right values by 100 to get decimal value between 1.00 and 4.00. It works when I change
Private Sub SetDefaults()
' Me.Orientation = Windows.Forms.Orientation.Horizontal
Me.Orientation = Orientation.Horizontal
Me.SmallChange = 1
Me.Maximum = 400
Me.Minimum = 0
Me.ValueLeft = 0
Me.ValueRight = 300
End Sub
and then set the properties of DoubleTrackBar1 to
Maximum: 400
Minimum: 0
ValueLeft: 100
ValueRight: 300
It crashed when I set the Minimum to 100.
Please help!
Thank you.
Fred
Tuesday, February 10, 2015 5:01 PM
I still can't get the ticks. I've changed
Private Sub SetDefaults()
' Me.Orientation = Windows.Forms.Orientation.Horizontal
Me.Orientation = Orientation.Horizontal
Me.SmallChange = 1
Me.Maximum = 400
Me.Minimum = 0
Me.ValueLeft = 0
Me.ValueRight = 300
End Sub
Which property is for display the ticks?
Thank you very much.
Fred
Tuesday, February 10, 2015 6:27 PM
Hi,
There should be Ticks if you adjust the height of the control to be bigger. I did not see them ether until i made its height larger. As far as adjusting the Min Max values i did not really look through the code but, it is probably throwing off some calculations in the code somewhere that are causing the error. It seems to be designed to not take a lot of these things into account.
This control seems to be very limited in its functionality and will probably require some reworking to make it function half way decent. I would recommend maybe trying one of the Range controls from the links below. They are written in C# and i did not try them out but, i would imagine you can add the Class Library dll to your toolbox using the (Tools/Choose ToolBox Items) menu option. If not then you can always add a Reference to the dll in your project and add them to the form from your code.
They are probably a lot more functional than the current one you are trying to use. Frank mentioned one in his post too but, that may be one you have to purchase.
A custom range selector control in C# (with a little animating slider)
CRangeSlider - a Ctrl for Selecting a Range or Interval
If i get a chance later i will look the code over to see if i can find why it throws that error but, i am kind of busy working on other things today. 8)
If you say it can`t be done then i`ll try it
Tuesday, February 10, 2015 7:44 PM
Hi,
I went through the code real quick and changed a couple lines in the code and reposted it in my original post that had the fixed code in it to keep this thread as short as possible. I added 2 lines in the SetDefaults sub to make the control big enough to see the Ticks when you add one to the form. I also set the values you wanted there too.
There is no property in this control to adjust the spacing of the Ticks so, i changed a little code in the OnPaint sub to keep a fairly decent spacing between the Ticks as the trackbar`s width is adjusted (its just for looks). While i was doing that i changed the code to show the Ticks at the top of the trackbar and to draw the top pointing thumb buttons. I don`t know if you really wanted that but, i think it is nicer than the upsidedown looking trackbar.
If you want it the other way then let me know and i will change it or tell you how to change it back. Also, if you are going to change any code in the trackbar class then depending on what you change, you may want to delete the trackbar from the form and then rebuild the project. Then add a new trackbar from the toolbox. It does not always cause problems but, i have seen times it will.
Here is what it looks like when i add a new one to the form in the [Design] tab.
If you say it can`t be done then i`ll try it
Tuesday, February 10, 2015 9:41 PM
Thank you, IronRazerz.
I got the ticks. I still have problem when set
Me.Maximum = 400
Me.Minimum = 100
Me.ValueLeft = 180
Me.ValueRight = 300
It crashes when build.
Thanks.
Friday, February 13, 2015 7:05 PM | 2 votes
I'm suing VB 2010 Express and I need to create a trackbar control with double trackbars.
I can't find "Doubletrackbar" control from Toolbox. I searched online and found one post toking about it (http://www.vbforums.com/showthread.php?620394-WIP-Double-TrackBar). Unfortunately, I can't use the code in the post. Anyone can help?
Thank you very much.
So here is my delayed response to this thread. I read it the other day and thought to myself, "why not?".
This example is independant of previously mentioned articles on the internet and does not quite work exactly as the one you had asked a question about. Instead this one works on the notion of the ability to add as many heads to the slider as you want to, with a partially customizable head. With these customizable heads, you can dictate the following:
- How many heads will be on the slider
- Which side of the slider they will be on(Top, Bottom, Left, or Right)
- The Pens and Brushes to be used, including support for linear gradient brushes
- The size of each individual slider head(Width, height, and tip length)
- Value changed event for each head
- Varying min and max values for each head
Please note* This example has not been fully tested and some errors may arise when attempting to do complex or strange things... I have made a code gallery, link at bottom of page.
Screenshot:
Code Gallery Link:
“If you want something you've never had, you need to do something you've never done.”
Don't forget to mark helpful posts and answers ! Answer an interesting question? Write a new article about it! My Articles |
*This post does not reflect the opinion of Microsoft, or its employees.
Friday, February 13, 2015 9:38 PM
Got it working Paul! Very nice.
Most of what I understand is the ATAN2 function.
:)
Friday, February 13, 2015 11:47 PM
Got it working Paul! Very nice.
Most of what I understand is the ATAN2 function.
:)
Thanks Tommy,
Theres a few things I noticed that I forgot to do... Such as add LGB support for all head orientations, that and I forgot to complete the LEFT and TOP properties of the slider head. One more interesting thing to note is that right now, I have not implemented support to change the minimum value to something other than 0. Just a few oversights on my part. But this control was a bit of a challenge, and I have quite a few ideas still to add options and features, so still got a ways to go.
“If you want something you've never had, you need to do something you've never done.”
Don't forget to mark helpful posts and answers ! Answer an interesting question? Write a new article about it! My Articles |
*This post does not reflect the opinion of Microsoft, or its employees.
Saturday, February 14, 2015 12:05 AM
@ Paul,
Yes that is pretty cool. I started a Double Trackbar similar to the one shown in my images above but, this definitely has a lot more functionality to it than mine will. I like the part of being able to set the Thumbs on opposite sides and the ability of setting the Min Max for each thumb. I was making mine so it is more of a range control where the thumbs can not pass each other. Yours has a lot broader range of possibilities for it though.
You really should put that on the Code Gallery when you finish it up. I think there would be a lot of hits on it. Plus it would be easier for everyone to find and reference a link to. 8)
If you say it can`t be done then i`ll try it
Saturday, February 14, 2015 12:08 AM
“If you want something you've never had, you need to do something you've never done.”
Don't forget to mark helpful posts and answers ! Answer an interesting question? Write a new article about it! My Articles |
*This post does not reflect the opinion of Microsoft, or its employees.
Saturday, February 14, 2015 12:17 AM
@ Paul,
Yes that is pretty cool. I started a Double Trackbar similar to the one shown in my images above but, this definitely has a lot more functionality to it than mine will. I like the part of being able to set the Thumbs on opposite sides and the ability of setting the Min Max for each thumb. I was making mine so it is more of a range control where the thumbs can not pass each other. Yours has a lot broader range of possibilities for it though.
You really should put that on the Code Gallery when you finish it up. I think there would be a lot of hits on it. Plus it would be easier for everyone to find and reference a link to. 8)
If you say it can`t be done then i`ll try it
Thanks for the compliment :-).
Anything with drawing always attracts my attention. I did plan on creating a wiki-article and a code gallery sample, but this example really isnt finished yet. I intend on making it to where it supports signed floating point ranges. Right now it supports integer ranges from a fixed 0 to a positive number. Of course there is outside logic that could be applied to implement the ladder. I am also adding a Pre-HeadRender event, that way someone could render their own graphics before the heads are rendered(such as custom tick-marks). I also plan on adding a Post-HeadRender paint event for the rendering of information above the heads. I also want to add support for custom head-polygons, and also even heads rendered from image resources. I really do have alot of ideas for this, but I was trying to get an example up here as quick as possible(still took what? 3 days?) I've probably had other ideas as well, which I will remember as I explore this idea further, any suggestions would be neat too.
“If you want something you've never had, you need to do something you've never done.”
Don't forget to mark helpful posts and answers ! Answer an interesting question? Write a new article about it! My Articles |
*This post does not reflect the opinion of Microsoft, or its employees.
Saturday, February 14, 2015 12:40 AM | 1 vote
Anything to do with custom controls and drawing is very interesting to me too. As i told Tom the other day, i guess i am just a "Control" freak. haha.
Yes the floating point values would be nice. It would save a little extra coding in the users form. The Pre and Post HeadRenders would be a nice addition too in case the user wants to do a little custom drawing. If your not careful your going to have to start charge money for this.
I have not tested it yet but, have read through and glanced through the code just to see what all was going on. Been pretty busy working on a few projects of my own lately but, i will give it a go later or tomorrow. It sound like you have enough ideas to keep you busy with it for a few more days anyways. Let us know when you get it up on the Code Gallery or wherever. I will surely post a link to it if i see another question like this. 8)
If you say it can`t be done then i`ll try it
Saturday, February 14, 2015 6:15 AM | 1 vote
Let us know when you get it up on the Code Gallery or wherever. I will surely post a link to it if i see another question like this.
IronRazerz,
I think I'm done for now...
Here is a link to Code Gallery:
“If you want something you've never had, you need to do something you've never done.”
Don't forget to mark helpful posts and answers ! Answer an interesting question? Write a new article about it! My Articles |
*This post does not reflect the opinion of Microsoft, or its employees.
Saturday, February 14, 2015 11:04 AM
Paul,
Got it, thanks Paul. I downloaded your class for Accessing and Modifying Binary Wave files too. That`s another part of programming that i am pretty interested in. 8)
If you say it can`t be done then i`ll try it
Saturday, February 14, 2015 12:52 PM
Let us know when you get it up on the Code Gallery or wherever. I will surely post a link to it if i see another question like this.
IronRazerz,
I think I'm done for now...
Here is a link to Code Gallery:
“If you want something you've never had, you need to do something you've never done.”
Don't forget to mark helpful posts and answers ! Answer an interesting question? Write a new article about it! My Articles
*This post does not reflect the opinion of Microsoft, or its employees.
Crazy man. I love how the sliderhead jumps to the top or bottom as you move it with the mouse.
You certainly are productive. I hope they pay you enough where you work. :)
Saturday, February 14, 2015 2:50 PM
Crazy man. I love how the sliderhead jumps to the top or bottom as you move it with the mouse.
You certainly are productive. I hope they pay you enough where you work. :)
That was a last minute idea I had. I got to thinking about how overlapping heads might prove to be an inconvenience, and that's the idea I went with to lessen the problem, the other option was incorporating a Z-order for the heads(which I should still probably do).
As far as getting paid enough... Maybe one day... :-)
“If you want something you've never had, you need to do something you've never done.”
Don't forget to mark helpful posts and answers ! Answer an interesting question? Write a new article about it! My Articles |
*This post does not reflect the opinion of Microsoft, or its employees.