none
Position Control diagram

    Question

  • Hi,

    I'm looking for a control that show position something like this that I can control minimum and maximum values

    I don't have any artistic ability to draw a position diagram and  I'm looking for something that exists and free for vb.net

    Thanks in advance

    Wednesday, March 22, 2017 10:13 AM

Answers

  • Here is one that is fairly easy.

    You can set any max min and sweep of the dial remains constant.

    'circular dial v3
    Imports System.Drawing.Drawing2D
    
    Public Class Form3
        Private WithEvents HScrollbar1 As New HScrollBar With {.Parent = Me, .Dock = DockStyle.Bottom}
        Private WithEvents Dial1 As New DialMax With
                {.Parent = Me, .Dock = DockStyle.Fill,
                .Max = 180, .Min = -180,
                .BackColor = Color.DarkSlateGray,
                .ForeColor = Color.AntiqueWhite,
                .DialColor = Color.SlateGray,
                .NeedleColor = Color.AliceBlue,
                .Font = New Font("tahoma", 10),
                .Increment = 30}
    
        Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            BackColor = Color.AliceBlue
            Text = "Custom Dial Example"
            HScrollbar1.Minimum = CInt(Dial1.Min)
            HScrollbar1.Maximum = CInt(Dial1.Max + 20)
            HScrollbar1.LargeChange = 20
            HScrollbar1.SmallChange = 1
            HScrollbar1.Value = 0
        End Sub
    
        Private Sub HScrollbar1_Scroll(sender As Object, e As ScrollEventArgs) Handles HScrollbar1.Scroll
            Dial1.Value = CInt(HScrollbar1.Value)
            Dial1.Invalidate()
        End Sub
    End Class
    
    Public Class DialMax
        Inherits Control
    
        Public Max As Double = 100
        Public Min As Double = -100
        Public Value As Integer = 0
        Public DialColor As Color = Color.White
        Public NeedleColor As Color = Color.Black
        Public Increment As Single = 20
    
        Sub New()
            DoubleBuffered = True
        End Sub
    
        Private Sub DialMax_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
            Dim AngleRatio As Double = 240 / (Max - Min)    'conversion from dial value to rotation angle
            Dim x1 As Integer = CInt(ClientSize.Width / 2)  'center of dial in picturebox center
            Dim y1 As Integer = CInt(ClientSize.Height / 2)
            Dim x2, y2, x3, y3 As Single
            Dim a As Double
            Dim stringSize As New SizeF
            Dim r As Double
            If ClientSize.Width > ClientSize.Height Then
                r = 0.47 * ClientSize.Height       'radius size
            Else
                r = 0.47 * ClientSize.Width       'radius size
            End If
    
            With e.Graphics
                Using pg As New Pen(Color.Silver, 2),
                    ps1 As New Pen(Color.Black, 3),
                    ps2 As New Pen(ForeColor, 1),
                    pNeedle As New Pen(Color.Black, 8),
                    f As New Font(Font.FontFamily, CSng(r / 12)),
                    f2 As New Font(Font.FontFamily, CSng(r / 8), FontStyle.Bold),
                    f3 As New Font(Font.FontFamily, CSng(r / 8)),
                    brg As New SolidBrush(BackColor),
                    brf1 As New SolidBrush(ForeColor)
    
                    .SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
                    .Clear(BackColor)
    
                    'dial face
                    Dim rect As New Rectangle(CInt(x1 - (0.7 * r)), CInt(y1 - (0.7 * r)), CInt(1.4 * r), CInt(1.4 * r))
    
                    Using path As New GraphicsPath()
                        path.AddEllipse(rect)
    
                        ' Use the path to construct a brush.
                        Using pthGrBrush As New PathGradientBrush(path)
                            pthGrBrush.CenterColor = DialColor
                            pthGrBrush.SurroundColors = {ForeColor}
                            .FillPath(pthGrBrush, path)
                        End Using
                    End Using
    
                    .DrawEllipse(New Pen(Color.Gray, 10), CInt(x1 - (0.7 * r)), CInt(y1 - (0.7 * r)), CInt(1.4 * r), CInt(1.4 * r))
                    .DrawEllipse(pg, CInt(x1 - (0.7 * r)), CInt(y1 - (0.7 * r)), CInt(1.4 * r), CInt(1.4 * r))
    
                    'scale
                    For t As Double = Min To Max + 5 Step Increment
                        a = ((t * AngleRatio) - 90) / 57.3
                        x2 = CInt(x1 + (0.65 * r * Math.Cos(a)))
                        y2 = CInt(y1 + (0.65 * r * Math.Sin(a)))
                        x3 = CInt(x1 + (0.75 * r * Math.Cos(a)))
                        y3 = CInt(y1 + (0.75 * r * Math.Sin(a)))
                        .DrawLine(ps1, x2, y2, x3, y3)
                        .DrawLine(ps2, x2, y2, x3, y3)
    
                        stringSize = .MeasureString((t).ToString("f0"), f)
                        x2 = CInt(x1 + (0.9 * r * Math.Cos(a)) - (stringSize.Width / 2))
                        y2 = CInt(y1 + (0.9 * r * Math.Sin(a)) - (stringSize.Height / 3))
                        .DrawString((t).ToString("f0"), f, brf1, x2, y2)
                    Next
    
                    'needle
                    a = ((Value * AngleRatio) - 90) / 57.3
                    x2 = CInt(x1 + 0.7 * r * Math.Cos(a))
                    y2 = CInt(y1 + 0.7 * r * Math.Sin(a))
                    pNeedle.EndCap = Drawing2D.LineCap.ArrowAnchor
                    pNeedle.StartCap = Drawing2D.LineCap.RoundAnchor
                    .DrawLine(pNeedle, x1, y1, x2, y2)
                    pNeedle.Width = 6
                    pNeedle.Color = NeedleColor
                    x2 = CInt(x1 + 0.68 * r * Math.Cos(a))
                    y2 = CInt(y1 + 0.68 * r * Math.Sin(a))
                    .DrawLine(pNeedle, x1, y1, x2, y2)
    
                    'value
                    brf1.Color = NeedleColor
                    .DrawString((Value).ToString("f0"), f3, brf1, x1 - 11, y1 + CInt(1.0 * r / 4))
                End Using
            End With
        End Sub
    
        Private Sub DialMax_Resize(sender As Object, e As EventArgs) Handles Me.Resize
            Refresh()
        End Sub
    End Class

    Wednesday, March 22, 2017 4:29 PM

All replies

  • Have not seen any for vb.net, here is a C# version, look at the demo and note the code to use should be easy to translate.

    https://www.codeproject.com/Articles/448562/An-Improved-Version-of-AGauge-A-fast-and-performin


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    Wednesday, March 22, 2017 2:34 PM
    Moderator
  • Here is one that is fairly easy.

    You can set any max min and sweep of the dial remains constant.

    'circular dial v3
    Imports System.Drawing.Drawing2D
    
    Public Class Form3
        Private WithEvents HScrollbar1 As New HScrollBar With {.Parent = Me, .Dock = DockStyle.Bottom}
        Private WithEvents Dial1 As New DialMax With
                {.Parent = Me, .Dock = DockStyle.Fill,
                .Max = 180, .Min = -180,
                .BackColor = Color.DarkSlateGray,
                .ForeColor = Color.AntiqueWhite,
                .DialColor = Color.SlateGray,
                .NeedleColor = Color.AliceBlue,
                .Font = New Font("tahoma", 10),
                .Increment = 30}
    
        Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            BackColor = Color.AliceBlue
            Text = "Custom Dial Example"
            HScrollbar1.Minimum = CInt(Dial1.Min)
            HScrollbar1.Maximum = CInt(Dial1.Max + 20)
            HScrollbar1.LargeChange = 20
            HScrollbar1.SmallChange = 1
            HScrollbar1.Value = 0
        End Sub
    
        Private Sub HScrollbar1_Scroll(sender As Object, e As ScrollEventArgs) Handles HScrollbar1.Scroll
            Dial1.Value = CInt(HScrollbar1.Value)
            Dial1.Invalidate()
        End Sub
    End Class
    
    Public Class DialMax
        Inherits Control
    
        Public Max As Double = 100
        Public Min As Double = -100
        Public Value As Integer = 0
        Public DialColor As Color = Color.White
        Public NeedleColor As Color = Color.Black
        Public Increment As Single = 20
    
        Sub New()
            DoubleBuffered = True
        End Sub
    
        Private Sub DialMax_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
            Dim AngleRatio As Double = 240 / (Max - Min)    'conversion from dial value to rotation angle
            Dim x1 As Integer = CInt(ClientSize.Width / 2)  'center of dial in picturebox center
            Dim y1 As Integer = CInt(ClientSize.Height / 2)
            Dim x2, y2, x3, y3 As Single
            Dim a As Double
            Dim stringSize As New SizeF
            Dim r As Double
            If ClientSize.Width > ClientSize.Height Then
                r = 0.47 * ClientSize.Height       'radius size
            Else
                r = 0.47 * ClientSize.Width       'radius size
            End If
    
            With e.Graphics
                Using pg As New Pen(Color.Silver, 2),
                    ps1 As New Pen(Color.Black, 3),
                    ps2 As New Pen(ForeColor, 1),
                    pNeedle As New Pen(Color.Black, 8),
                    f As New Font(Font.FontFamily, CSng(r / 12)),
                    f2 As New Font(Font.FontFamily, CSng(r / 8), FontStyle.Bold),
                    f3 As New Font(Font.FontFamily, CSng(r / 8)),
                    brg As New SolidBrush(BackColor),
                    brf1 As New SolidBrush(ForeColor)
    
                    .SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
                    .Clear(BackColor)
    
                    'dial face
                    Dim rect As New Rectangle(CInt(x1 - (0.7 * r)), CInt(y1 - (0.7 * r)), CInt(1.4 * r), CInt(1.4 * r))
    
                    Using path As New GraphicsPath()
                        path.AddEllipse(rect)
    
                        ' Use the path to construct a brush.
                        Using pthGrBrush As New PathGradientBrush(path)
                            pthGrBrush.CenterColor = DialColor
                            pthGrBrush.SurroundColors = {ForeColor}
                            .FillPath(pthGrBrush, path)
                        End Using
                    End Using
    
                    .DrawEllipse(New Pen(Color.Gray, 10), CInt(x1 - (0.7 * r)), CInt(y1 - (0.7 * r)), CInt(1.4 * r), CInt(1.4 * r))
                    .DrawEllipse(pg, CInt(x1 - (0.7 * r)), CInt(y1 - (0.7 * r)), CInt(1.4 * r), CInt(1.4 * r))
    
                    'scale
                    For t As Double = Min To Max + 5 Step Increment
                        a = ((t * AngleRatio) - 90) / 57.3
                        x2 = CInt(x1 + (0.65 * r * Math.Cos(a)))
                        y2 = CInt(y1 + (0.65 * r * Math.Sin(a)))
                        x3 = CInt(x1 + (0.75 * r * Math.Cos(a)))
                        y3 = CInt(y1 + (0.75 * r * Math.Sin(a)))
                        .DrawLine(ps1, x2, y2, x3, y3)
                        .DrawLine(ps2, x2, y2, x3, y3)
    
                        stringSize = .MeasureString((t).ToString("f0"), f)
                        x2 = CInt(x1 + (0.9 * r * Math.Cos(a)) - (stringSize.Width / 2))
                        y2 = CInt(y1 + (0.9 * r * Math.Sin(a)) - (stringSize.Height / 3))
                        .DrawString((t).ToString("f0"), f, brf1, x2, y2)
                    Next
    
                    'needle
                    a = ((Value * AngleRatio) - 90) / 57.3
                    x2 = CInt(x1 + 0.7 * r * Math.Cos(a))
                    y2 = CInt(y1 + 0.7 * r * Math.Sin(a))
                    pNeedle.EndCap = Drawing2D.LineCap.ArrowAnchor
                    pNeedle.StartCap = Drawing2D.LineCap.RoundAnchor
                    .DrawLine(pNeedle, x1, y1, x2, y2)
                    pNeedle.Width = 6
                    pNeedle.Color = NeedleColor
                    x2 = CInt(x1 + 0.68 * r * Math.Cos(a))
                    y2 = CInt(y1 + 0.68 * r * Math.Sin(a))
                    .DrawLine(pNeedle, x1, y1, x2, y2)
    
                    'value
                    brf1.Color = NeedleColor
                    .DrawString((Value).ToString("f0"), f3, brf1, x1 - 11, y1 + CInt(1.0 * r / 4))
                End Using
            End With
        End Sub
    
        Private Sub DialMax_Resize(sender As Object, e As EventArgs) Handles Me.Resize
            Refresh()
        End Sub
    End Class

    Wednesday, March 22, 2017 4:29 PM
  • Hi

    Is that a typo at:

     With e.Graphics
                Using pg As New Pen(Color.Silver, 2),
                    ps1 As New Pen(Color.Black, 3),
                    ps2 As New Pen(ForeColor, 1),
                    pr = New Pen(Color.LightGoldenrodYellow, 6),
                    f As New Font("arial", CSng(r / 10)),
                    f2 As New Font("arial", CSng(r / 6)),
                    brg As New SolidBrush(BackColor),
                    brf As New SolidBrush(ForeColor)
    maybe pr As New .........


    Regards Les, Livingston, Scotland


    • Edited by leshay Wednesday, March 22, 2017 5:32 PM
    Wednesday, March 22, 2017 5:31 PM
  • Tommy,

    You definitely have a knack for graphics. :)


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Wednesday, March 22, 2017 6:24 PM
  • Hi

    Is that a typo at:

     With e.Graphics
                Using pg As New Pen(Color.Silver, 2),
                    ps1 As New Pen(Color.Black, 3),
                    ps2 As New Pen(ForeColor, 1),
                    pr = New Pen(Color.LightGoldenrodYellow, 6),
                    f As New Font("arial", CSng(r / 10)),
                    f2 As New Font("arial", CSng(r / 6)),
                    brg As New SolidBrush(BackColor),
                    brf As New SolidBrush(ForeColor)
    maybe pr As New .........


    Regards Les, Livingston, Scotland


    I think some of the new versions allow that now. Or old. Seems to work?

    Thanks Frank.


    PS Oh maybe that is option implicit.
    Wednesday, March 22, 2017 7:12 PM