Title | Use a PictureBox to make a slider with a needle in Visual Basic .NET |
Description | This example shows how to use a PictureBox to make a slider with a needle in Visual Basic .NET. |
Keywords | controls, PictureBox, slider, TrackBar, MouseDown, MouseMove, MouseUp, ToolTip, Visual Basic .NET, VB.NET |
Categories | Controls, Controls, Controls |
|
|
This example draws a vertical "needle" in a PictureBox to let the user select a value much as a TrackBar does. The code does all of the drawing, however, so you have control over the slider's appearance. The example also displays the current value in a tooltip above the slider.
The program uses a variable and two constants to track the slider's value and its minimum and maximum allowed values.
|
|
' The current value.
Private SliderValue As Single = 0.3
' The minimum and maximum allowed values.
Private Const MinimumValue As Single = 0.0
Private Const MaximumValue As Single = 1.0
|
|
The program uses two methods to convert between X coordinates in the PictureBox and values between the minimum and maximum allowed values.
|
|
' Convert an X coordinate to a value.
Private Function XtoValue(ByVal x As Integer) As Single
Return MinimumValue + (MaximumValue - MinimumValue) * _
x / CSng(picSlider.ClientSize.Width - 1)
End Function
' Convert value to an X coordinate.
Private Function ValueToX(ByVal value As Single) As Single
Return (picSlider.ClientSize.Width - 1) * _
(value - MinimumValue) / CSng(MaximumValue - _
MinimumValue)
End Function
|
|
This is just math. The only trick here is that the code subtracts 1 from the PictureBox's client width to map the rightmost visible pixel in the PictureBox to the largest allowed value. If you don't do this, then when the user selects the large allowed value the needle isn't visible because it is one pixel to the right of the edge of the control's client area.
When the user presses the mouse down on the PictureBox or moves the pressed mouse over the PictureBox, the MouseDown or MouseMove event handlers call the SetValue method to update the slider's value.
|
|
' Move the needle to this position.
Private MouseIsDown As Boolean = False
Private Sub picSlider_MouseDown(ByVal sender As _
System.Object, ByVal e As _
System.Windows.Forms.MouseEventArgs) Handles _
picSlider.MouseDown
MouseIsDown = True
SetValue(XtoValue(e.X))
End Sub
Private Sub picSlider_MouseMove(ByVal sender As _
System.Object, ByVal e As _
System.Windows.Forms.MouseEventArgs) Handles _
picSlider.MouseMove
If (Not MouseIsDown) Then Return
SetValue(XtoValue(e.X))
End Sub
|
|
When the user releases the mouse, the following event handler sets MouseIsDown so future MouseMove events don't do anything.
|
|
Private Sub picSlider_MouseUp(ByVal sender As System.Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) Handles _
picSlider.MouseUp
MouseIsDown = False
tipValue.Hide(Me)
' Take action here if desired.
lblResult.Text = SliderValue.ToString("0.00")
End Sub
|
|
The SetValue method updates the slider's value.
|
|
' Set the slider's value. If the value has changed,
' display the value tooltip.
Private Sub SetValue(ByVal value As Single)
' Make sure the new value is within bounds.
If (value < MinimumValue) Then value = MinimumValue
If (value > MaximumValue) Then value = MaximumValue
' See if the value has changed.
If (SliderValue = value) Then Return
' Save the new value.
SliderValue = value
' Redraw to show the new value.
picSlider.Refresh()
' Display the value tooltip.
Dim tip_x As Integer = picSlider.Left + _
CInt(ValueToX(SliderValue))
Dim tip_y As Integer = picSlider.Top
tipValue.Show(SliderValue.ToString("0.00"), Me, tip_x, _
tip_y, 3000)
' Take action here if desired.
lblResult.Text = SliderValue.ToString("0.00")
End Sub
|
|
The code first ensures that the new value is within range. If the user presses the mouse down over the control and then drags it to the right or left of the PictureBox, the value could be outside of the allowed range so this code fixes it.
Next if the new value and the old value are the same, the method exits.
If the method doesn't exit, it saves the new value and refreshes the PictureBox so it shows the new needle position. It then displays the new value in a tooltip above the PictureBox. Finally in this example the code displays the new value in a label.
The last piece of interesting code is the PictureBox's Paint event handler.
|
|
' Draw the needle.
Private Sub picSlider_Paint(ByVal sender As System.Object, _
ByVal e As System.Windows.Forms.PaintEventArgs) Handles _
picSlider.Paint
' Calculate the needle's X coordinate.
Dim x As Single = ValueToX(SliderValue)
' Draw it.
e.Graphics.DrawLine(Pens.Blue, _
x, 0, _
x, picSlider.ClientSize.Height)
End Sub
|
|
This code simply draws the needle at the corrent position.
Using a SetValue method may seem overly elaborate. You could simply set the new value directly and then refresh the PictureBox in the MouseDown and MouseMove event handlers. The program uses SetValue to avoid doing anything if the value doesn't change. That's important to avoid flicker caused by unnecessary redraws and unnecessarily redisplaying the tooltip.
|
|
|
|
|
|
|