• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 5844
  • Last Modified:

circular progress bar (VB.NET 2010)

Hi Experts,

I want to create a simple quiz app (WINFORM) (e.g. 10 questions). The score will be in a circle and I want some kind of progress bar wrapped around the circle... if player gets a point, the score +1 and progress percentage is displayed. I've no idea what best method to achieve this is... drawing a circle or using multiple images or manipulating a progress bar.

Please see image for reference.

Thanks,
Roberto

images.jpg
0
RobertoFreemano
Asked:
RobertoFreemano
  • 4
  • 3
1 Solution
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Here's a basic circular progress bar:
*Set the Font, ForeColor, and PercentageColor Properties*
Idle-Mind-517959.flv

Imports System.Drawing.Drawing2D
Public Class CircleProgressBar
    Inherits UserControl

    Private center As Point
    Private distance As Integer
    Private Value As Integer
    Private clr As Color

    Public Property Percentage As Integer
        Get
            Return Me.Value
        End Get
        Set(ByVal value As Integer)
            If value >= 0 AndAlso value <= 100 Then
                Me.Value = value
                Me.Refresh()
            End If
        End Set
    End Property

    Public Property PercentageColor As Color
        Get
            Return Me.clr
        End Get
        Set(ByVal value As Color)
            Me.clr = value
        End Set
    End Property

    Public Sub New()
        Me.DoubleBuffered = True
    End Sub

    Private Function GetPoint(ByVal cx As Single, ByVal cy As Single, ByVal angleInDegrees As Single, ByVal distance As Single) As Point
        ' angleInDegrees
        ' Valid values are 0 --> 359 (six degrees = one minute on clock)
        ' draw a line from the center of the circle:
        ' 0 = up
        ' 90 = right
        ' 180 = down
        ' 270 = left

        angleInDegrees = (angleInDegrees - 90) * Math.PI / 180

        ' Compute the point that is at the specified angle clockwise from straight up vertical and at the specifed distance
        Return New Point(cx + distance * Math.Cos(angleInDegrees), cy + distance * Math.Sin(angleInDegrees))
    End Function

    Private Sub CircularProgressBar_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize
        Me.Refresh()
    End Sub

    Private Sub CircularProgressBar_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
        Dim G As Graphics = e.Graphics
        center = New Point(Me.Width / 2, Me.Height / 2)

        Dim rc As New Rectangle(center.X, center.Y, 1, 1)
        rc.Inflate((Math.Min(Me.Width, Me.Height) / 2) * 0.85, (Math.Min(Me.Width, Me.Height) / 2) * 0.85)
        G.FillEllipse(Brushes.Gray, rc)

        rc = New Rectangle(center.X, center.Y, 1, 1)
        rc.Inflate((Math.Min(Me.Width, Me.Height) / 2) * 0.65, (Math.Min(Me.Width, Me.Height) / 2) * 0.65)
        G.FillEllipse(Brushes.White, rc)

        rc = New Rectangle(center.X, center.Y, 1, 1)
        rc.Inflate((Math.Min(Me.Width, Me.Height) / 2) * 0.45, (Math.Min(Me.Width, Me.Height) / 2) * 0.45)
        G.FillEllipse(Brushes.Gray, rc)

        Dim percentageRing As New GraphicsPath()
        percentageRing.AddLines(BuildPercentageRing(center.X, center.Y, Me.Percentage, (Math.Min(Me.Width, Me.Height) / 2) * 0.7, (Math.Min(Me.Width, Me.Height) / 2) * 0.8).ToArray)
        Using B2 As New SolidBrush(Me.PercentageColor)
            G.FillPath(B2, percentageRing)
        End Using
        G.DrawPath(Pens.Black, percentageRing)

        Dim txt As String = Me.Percentage & "%"
        Dim szF As SizeF = G.MeasureString(txt, Me.Font)
        Using B As New SolidBrush(Me.ForeColor)
            G.DrawString(txt, Me.Font, B, New Point(center.X - szF.Width / 2, center.Y - szF.Height / 2))
        End Using
    End Sub

    Private Function BuildPercentageRing(ByVal cx As Single, ByVal cy As Single, ByVal percentage As Integer, _
        ByVal innerDistance As Single, ByVal outerDistance As Single) As List(Of Point)

        Dim pList As New List(Of Point)
        pList.Add(GetPoint(cx, cy, 0, outerDistance))
        For i As Integer = 0 To percentage
            pList.Add(GetPoint(cx, cy, (CDbl(i) / CDbl(100)) * 360, outerDistance))
            If i Mod 5 = 0 Then
                pList.Add(GetPoint(cx, cy, (CDbl(i) / CDbl(100)) * 360, innerDistance))
                pList.Add(GetPoint(cx, cy, (CDbl(i) / CDbl(100)) * 360, outerDistance))
            End If
        Next
        For i As Integer = percentage To 0 Step -1
            pList.Add(GetPoint(cx, cy, (CDbl(i) / CDbl(100)) * 360, innerDistance))
        Next
        Return pList
    End Function

End Class

Open in new window

0
 
RobertoFreemanoAuthor Commented:
Sorry Mike,

I know it's me but i got erros :(

I created a new form2 to test the code.
Warning	2	'Public Sub New()' in designer-generated type 'Printer_Q.Form2' should call InitializeComponent method.	C:\Documents and Settings\bob_2\my documents\visual studio 2010\Projects\Printer_Q\Printer_Q\Form2.vb	30	16	Printer_Q

from line 31

Open in new window

Error	1	Base class 'System.Windows.Forms.UserControl' specified for class 'Form2' cannot be different from the base class 'System.Windows.Forms.Form' of one of its other partial types.	C:\Documents and Settings\bob_2\my documents\visual studio 2010\Projects\Printer_Q\Printer_Q\Form2.vb	3	14	Printer_Q

from line 3

Open in new window

0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
No problem.

Click on Project --> Add User Control, type in CircleProgressBar, and then click on Add.
Hit F7 to view the code for the UserControl.
Paste the code above, except for line #3, over the code that is there.
Run the Project to make it compile.
Go back to the main Form.
You should now have a new control, CircleProgressBar, at the top of your ToolBox.
Drag one to your Form.

Change the ForeColor and Font properties to adjust the Text in the Middle.
Change the PercentageColor to change the color of the circular bar.

Change the Percentage() property to set the value at run-time:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        For i As Integer = 1 To 100
            CircleProgressBar1.Percentage = i
            Application.DoEvents()
            System.Threading.Thread.Sleep(250)
        Next
    End Sub

Open in new window

0
Get free NFR key for Veeam Availability Suite 9.5

Veeam is happy to provide a free NFR license (1 year, 2 sockets) to all certified IT Pros. The license allows for the non-production use of Veeam Availability Suite v9.5 in your home lab, without any feature limitations. It works for both VMware and Hyper-V environments

 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Did you ever get this to work for you Roberto?
0
 
RobertoFreemanoAuthor Commented:
Hi Mike,

Sorry, i didn't get chance yet.... I'll try this tonight :)
Thanks,
Rob
0
 
RobertoFreemanoAuthor Commented:
Hi Mike,

Sorry, i didn't get chance yet.... I'll try this tonight :)
Thanks,
Rob
0
 
RobertoFreemanoAuthor Commented:
Thanks Mike,

Sorry it took me so long to get back to you ;)

Thanks again,
Roberto
0

Featured Post

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

  • 4
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now