Results 1 to 38 of 38

Thread: [WIP] Customizable ProgressBar

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    [WIP] Customizable ProgressBar

    Hey,

    [This is still a Work In Progress, so not finished yet!]


    I noticed a few requests on how to draw your own ProgressBar, so I decided to make one myself. Instead of simply providing one drawing style and having you edit the control to suit your needs, I decided to make it customizable instead.

    The ProgressBarEx control provides you with PaintBackground and PaintProcess events.

    The PaintBackground event fires when the background is painted and passes the Graphics and ClipRectangle objects you need to draw the background manually. You could draw a gradient, a picture, a solid color, whatever you like, instead of the default BackColor.

    The PaintProcess event fires when the process part of the ProgressBar is painted (the bar that shows how far the progress is). It also provides you with the Graphics object, and the Bounds object that represents the 'process rectangle'. So, you do not need to calculate the size and location of that rectangle manually, it is given to you in this event. You simply need to create your desired brush, and draw it.

    Since there is also a Blocks style, like the normal ProgressBar, the PaintProcess event also provides you with a Blocks Rectangle array. Each Rectangle in that array represents one block. You can loop through the blocks and paint each block the same, or you could paint each block with a random color, or you could have a gradient going smoothly from left to right. Again, the rectangles you need for the drawing are all given to you, no calculation required.

    For the Blocks style, there are also the BlockWidth and BlockSeparation property, which are straightforward; they set the width and separation of the blocks.

    The ProgressBar also shows the relative value (49%) in the middle. You can turn that off with the ShowValue property.

    If you don't require or want to do fancy custom drawing, you can simply set the BackColor (for the background) and Color (for the process bar color) properties, and you will have either a continuous, or block, ProgressBar in that color.

    I am also working on a Marquee style with animation, and an Orientation property which allows you to have a vertical ProgressBar, but those are not functional yet.


    The ProgressBar looks like this by default, in the Continuous style:

    Pretty simple. But the custom drawing can now begin!


    Here are a few examples on custom drawing the ProgressBar.

    Example 1 - A horizontal gradient in a continuous bar.
    Using the PaintProcess event and the EventArguments it passes, we can simply draw a gradient on the process bar, leaving the background simply the BackColor.
    vb.net Code:
    1. Private Sub ProgressBarEx1_PaintProcess(ByVal sender As System.Object, ByVal e As ProgressBarEx.ProgressBarEx.ProgressBarProcessPaintEventArgs) Handles ProgressBarEx1.PaintProcess
    2.         Using b As New Drawing2D.LinearGradientBrush(e.Bounds, _
    3.                                                      Color.DarkBlue, _
    4.                                                      Color.LightBlue, _
    5.                                                      Drawing2D.LinearGradientMode.Horizontal)
    6.             e.Graphics.FillRectangle(b, e.Bounds)
    7.         End Using
    8.     End Sub
    Result:


    That was easy, wasn't it?


    Example 2 - Drawing red and blue blocks interchangebly.
    Next, we will use the Blocks style and draw the first block red, then blue, red, blue, etc. We use a simple For loop for this, and use the Mod operator to check if the loop iterator is even (i Mod 2 = 0) or odd. If it's even, we draw red, otherwise blue.
    vb.net Code:
    1. Private Sub ProgressBarEx1_PaintProcess(ByVal sender As System.Object, ByVal e As ProgressBarEx.ProgressBarEx.ProgressBarProcessPaintEventArgs) Handles ProgressBarEx1.PaintProcess
    2.         Dim brush As New SolidBrush(Color.Red)
    3.         For i As Integer = 0 To e.Blocks.Length - 1
    4.             If (i Mod 2 = 0) Then  'i is even
    5.                 brush = New SolidBrush(Color.Red)
    6.             Else
    7.                 brush = New SolidBrush(Color.Blue)
    8.             End If
    9.  
    10.             e.Graphics.FillRectangle(brush, e.Blocks(i))
    11.         Next
    12.         brush.Dispose()
    13.     End Sub
    Result:

    Ok, not very pretty, but the concept is clear.


    Finally, let's try something a bit more complicated
    Example 3 - Horizontal gradient with horizontal white accents
    Here, I draw a horizontal gradient from red to darkred, across the entire process area, smoothly between each block. I also use a second white gradient to highlight each block separately. Finally, I also draw a black border around each block.
    vb.net Code:
    1. Private Sub ProgressBarEx1_PaintProcess(ByVal sender As System.Object, ByVal e As ProgressBarEx.ProgressBarEx.ProgressBarProcessPaintEventArgs) Handles ProgressBarEx1.PaintProcess
    2.         For Each b As Rectangle In e.Blocks
    3.             Using totalBrush As New Drawing2D.LinearGradientBrush(e.Bounds, _
    4.                                                     Color.Red, _
    5.                                                     Color.DarkRed, _
    6.                                                     Drawing2D.LinearGradientMode.Horizontal)
    7.                 e.Graphics.FillRectangle(totalBrush, b)
    8.             End Using
    9.             Using whiteBrush As New Drawing2D.LinearGradientBrush(b, _
    10.                                                                   Color.White, _
    11.                                                                   Color.Transparent, _
    12.                                                                   Drawing2D.LinearGradientMode.Horizontal)
    13.                 e.Graphics.FillRectangle(whiteBrush, b)
    14.             End Using
    15.             b = New Rectangle(b.X, b.Y, b.Width, b.Height - 1)
    16.             e.Graphics.DrawRectangle(Pens.Black, b)
    17.         Next
    18.     End Sub
    Result:



    As you can see, the code is still very easy, but the result is becoming more and more complicated. Since you don't have to worry about calculating the correct width of the rectangles you have to draw, you can concentrate on just drawing them. You could also draw rounded rectangles or circles instead of blocks if you want. You can draw whatever you want!


    You can also just use this as an example of how to draw your own ProgressBar.


    The code for the ProgressBarEx class is in the next post, as this one got too long!


    Good luck!

  2. #2

    Thread Starter
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Re: [WIP] Customizable ProgressBar

    Finally, here is the code of the ProgressBarEx class. Just add a new UserControl, call it ProgressBarEx, and copy/paste this code. Then Build your project, and it should be at the top of your Toolbox.

    Code:
    Public Class ProgressBarEx
    
    #Region " Properties "
    
        Private _Value As Integer = 0
        Public Property Value() As Integer
            Get
                Return _Value
            End Get
            Set(ByVal value As Integer)
                If value >= Me.MinValue And value <= Me.MaxValue Then
                    _Value = value
                    Me.Invalidate()
                Else
                    Throw New ArgumentOutOfRangeException("The value must be between the minimum and maximum values.")
                End If
            End Set
        End Property
    
        Private _Step As Integer = 10
        Public Property [Step]() As Integer
            Get
                Return _Step
            End Get
            Set(ByVal value As Integer)
                _Step = value
            End Set
        End Property
    
        Private _Orientation As ProgressBarOrientation
        Public Property Orientation() As ProgressBarOrientation
            Get
                Return _Orientation
            End Get
            Set(ByVal value As ProgressBarOrientation)
                _Orientation = value
            End Set
        End Property
    
        Private _MinValue As Integer = 0
        Public Property MinValue() As Integer
            Get
                Return _MinValue
            End Get
            Set(ByVal value As Integer)
                If value < Me.MaxValue Then
                    _MinValue = value
                Else
                    Throw New ArgumentOutOfRangeException("The minimum value must be less than the maximum value.")
                End If
            End Set
        End Property
    
        Private _MaxValue As Integer = 100
        Public Property MaxValue() As Integer
            Get
                Return _MaxValue
            End Get
            Set(ByVal value As Integer)
                If value > Me.MinValue Then
                    _MaxValue = value
                Else
                    Throw New ArgumentOutOfRangeException("The maximum value must be more than the minimum value.")
                End If
            End Set
        End Property
    
        Private _Color As Color = Color.Lime
        Public Property Color() As Color
            Get
                Return _Color
            End Get
            Set(ByVal value As Color)
                _Color = value
            End Set
        End Property
    
        Private _ShowValue As Boolean = True
        Public Property ShowValue() As Boolean
            Get
                Return _ShowValue
            End Get
            Set(ByVal value As Boolean)
                _ShowValue = value
            End Set
        End Property
    
        Private _Style As ProgressBarExStyle
        Public Property Style() As ProgressBarExStyle
            Get
                Return _Style
            End Get
            Set(ByVal value As ProgressBarExStyle)
                _Style = value
            End Set
        End Property
    
        Private _BlockWidth As Integer = 5
        Public Property BlockWidth() As Integer
            Get
                Return _BlockWidth
            End Get
            Set(ByVal value As Integer)
                _BlockWidth = value
            End Set
        End Property
    
        Private _BlockSeparation As Integer = 3
        Public Property BlockSeparation() As Integer
            Get
                Return _BlockSeparation
            End Get
            Set(ByVal value As Integer)
                _BlockSeparation = value
            End Set
        End Property
    
    #End Region
    
    #Region " Enums, Variables "
    
        Public Enum ProgressBarOrientation
            Horizontal = 0
            Vertical = 1
        End Enum
    
        Public Enum ProgressBarExStyle
            Blocks = 0
            Continuous = 1
            Marquee = 2
        End Enum
    
    #End Region
    
    #Region " Events "
    
        Public Event PaintBackground(ByVal sender As Object, ByVal e As PaintEventArgs)
        Public Event PaintProcess(ByVal sender As Object, ByVal e As ProgressBarProcessPaintEventArgs)
    
        Public Class ProgressBarProcessPaintEventArgs
            Inherits EventArgs
    
            Public Sub New(ByVal bounds As Rectangle, ByVal g As Graphics, Optional ByVal blocks() As Rectangle = Nothing)
                _Bounds = bounds
                _Graphics = g
                If blocks Is Nothing Then
                    _Blocks = New Rectangle() {}
                Else
                    _Blocks = blocks
                End If
            End Sub
    
            Private _Bounds As Rectangle
            Public ReadOnly Property Bounds() As Rectangle
                Get
                    Return _Bounds
                End Get
            End Property
    
            Private _Blocks As Rectangle()
            Public ReadOnly Property Blocks() As Rectangle()
                Get
                    Return _Blocks
                End Get
            End Property
    
            Private _Graphics As Graphics
            Public ReadOnly Property Graphics() As Graphics
                Get
                    Return _Graphics
                End Get
            End Property
    
        End Class
    
    #End Region
    
    #Region " Methods "
    
        Public Sub PerformStep()
            If Me.Step > 0 Then
                Me.Value = Math.Min(Me.Value + Me.Step, Me.MaxValue)
            Else
                Me.Value = Math.Max(Me.Value + Me.Step, Me.MinValue)
            End If
        End Sub
    
        Public Sub Increment(ByVal value As Integer)
            If value > 0 Then
                Me.Value = Math.Min(Me.Value + value, Me.MaxValue)
            Else
                Me.Value = Math.Max(Me.Value + value, Me.MinValue)
            End If
        End Sub
    
    #End Region
    
    #Region " Process Logic "
    
        Private Function GetProcessRect() As Rectangle
            Dim w As Integer = Me.Width
            Dim h As Integer = Me.Height
            Dim valRel As Integer = GetRelativeValue()
            Return New Rectangle(0, 0, w * valRel \ 100, h)
        End Function
    
        Private Function GetBlocks() As Rectangle()
            Dim b As New List(Of Rectangle)
    
            Dim w As Integer = Me.BlockWidth
            Dim h As Integer = Me.Height
            Dim r As Rectangle
    
            Dim x As Integer = 0
            Dim stopX As Integer = CInt((GetRelativeValue() / 100) * Me.Width)
            While (x + w <= stopX)
                r = New Rectangle(x, 0, w, h)
                b.Add(r)
    
                x += Me.BlockWidth + Me.BlockSeparation
            End While
    
            Return b.ToArray
        End Function
    
        Private Function GetRelativeValue() As Integer
            Return CInt(100 * Me.Value / (Me.MaxValue - Me.MinValue))
        End Function
    
    #End Region
    
    #Region " Drawing "
    
        Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
            MyBase.OnPaint(e)
            DoPaintBackground(e.Graphics)
            DoPaintProcess(e.Graphics)
            If Me.ShowValue Then DoPaintValue(e.Graphics)
        End Sub
    
        Private Sub DoPaintBackground(ByVal g As Graphics)
            RaiseEvent PaintBackground(Me, New PaintEventArgs(g, Me.ClientRectangle))
        End Sub
    
        Private Sub DoPaintProcess(ByVal g As Graphics)
            Dim rect As Rectangle = GetProcessRect()
            Dim blocks() As Rectangle = GetBlocks()
            Using brush As New SolidBrush(Me.Color)
                If Me.Style = ProgressBarExStyle.Continuous Then
                    g.FillRectangle(brush, rect)
                ElseIf Me.Style = ProgressBarExStyle.Blocks Then
                    For Each b As Rectangle In blocks
                        g.FillRectangle(brush, b)
                    Next
                End If
            End Using
    
            Dim e As New ProgressBarProcessPaintEventArgs(rect, g, blocks)
            RaiseEvent PaintProcess(Me, e)
        End Sub
    
        Private Sub DoPaintValue(ByVal g As Graphics)
            Dim valStr As String = GetRelativeValue.ToString & "&#37;"
            Dim sf As New StringFormat()
            sf.Alignment = StringAlignment.Center
            Dim s As SizeF = g.MeasureString(valStr, Me.Font)
    
            g.DrawString(valStr, Me.Font, New SolidBrush(Me.ForeColor), (Me.Width - s.Width) / 2, (Me.Height - s.Height) / 2)
        End Sub
    
    #End Region
    
    End Class

  3. #3

  4. #4

  5. #5

  6. #6

  7. #7
    Fanatic Member
    Join Date
    Oct 2008
    Location
    Dominican Republic
    Posts
    733

    Re: [WIP] Customizable ProgressBar

    Is there any way to stop the progressbar from flicking? And why does mine have like 1&#37; of the color as the second gradient color? If I choose it to begin the gradient with blue and end it with white, the first percent has a white color, but after that, works like a charm.

    Btw, great class Nick!
    "In our profession, precision and perfection are not a dispensable luxury, but a simple necessity."
    Niklaus E. Wirth


    Rate any post that helped you, it's a good way of saying thanks
    Please specify your Visual Studio Version!

    Why rating is useful

    My Code Bank Submissions: How to determine Windows Version| Working With Mouse Events | Blocking Input Using API | Get host's IP | Minimize to system tray "animated" | Colored ListBox (custom fonts, colors, highlight) Updated -New Class! | [VS 2008] Strong encryption and hashing class - Updated! 31/August/2009 | Create a shortcut using IWshRuntimeLibrary

  8. #8

    Thread Starter
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Re: [WIP] Customizable ProgressBar

    I didn't notice any flickering, but if you do you can try to setting the following ControlStyles, by adding this code:
    vb.net Code:
    1. Public Sub New()
    2.    Me.SetStyles(ControlStyles.AllPaintingInWmPaint, True)
    3.    Me.SetStyles(ControlStyles.ResizeRedraw, True)
    4.    Me.SetStyles(ControlStyles.UserPaint, True)
    5.    Me.SetStyles(ControlStyles.DoubleBuffer, True)
    6. End Sub
    There may be a few slight typo's there as I typed this right here in the browser, but you should be able to find the right ones.

    For the drawing, what is your code for the drawing? Perhaps the Rectangle you pass to the LinearGradientBrush is wrong.

  9. #9
    Fanatic Member
    Join Date
    Oct 2008
    Location
    Dominican Republic
    Posts
    733

    Re: [WIP] Customizable ProgressBar

    I changed the paint process to this:

    vb.net Code:
    1. Private Sub DoPaintProcess(ByVal g As Graphics)
    2.         Dim rect As Rectangle = GetProcessRect()
    3.         Dim blocks() As Rectangle = GetBlocks()
    4.         Using b As New Drawing2D.LinearGradientBrush(Me.Bounds, _
    5.                                                      Color.Red, _
    6.                                                      Color.White, _
    7.                                                      Drawing2D.LinearGradientMode.Horizontal)
    8.             g.FillRectangle(b, rect)
    9.         End Using
    10.         Dim e As New ProgressBarProcessPaintEventArgs(rect, g, blocks)
    11.         RaiseEvent PaintProcess(Me, e)
    12.     End Sub

    In reference to your code, I don't know what to do with SetStyles, it says: "SetStyles is not a member of ProgressBarEx."
    "In our profession, precision and perfection are not a dispensable luxury, but a simple necessity."
    Niklaus E. Wirth


    Rate any post that helped you, it's a good way of saying thanks
    Please specify your Visual Studio Version!

    Why rating is useful

    My Code Bank Submissions: How to determine Windows Version| Working With Mouse Events | Blocking Input Using API | Get host's IP | Minimize to system tray "animated" | Colored ListBox (custom fonts, colors, highlight) Updated -New Class! | [VS 2008] Strong encryption and hashing class - Updated! 31/August/2009 | Create a shortcut using IWshRuntimeLibrary

  10. #10

    Thread Starter
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Re: [WIP] Customizable ProgressBar

    First of all, you are supposed to use this control by handling the PaintProcess event, instead of changing the actual UserControl code. Still, I can't see anything wrong with your code so I dunno why it doesn't paint correctly. Can you show me a screenshot of what it does?

    Oh and SetStyles is supposed to be SetStyle, sorry.

  11. #11
    Fanatic Member
    Join Date
    Oct 2008
    Location
    Dominican Republic
    Posts
    733

    Re: [WIP] Customizable ProgressBar

    Hmph, seems like there must be something wrong with my eyes. I tried taking two screen shots, but the flickering isn't visible on the shot. I'll check my code later on.

    SetStyle should be in the UserControl code, right?
    "In our profession, precision and perfection are not a dispensable luxury, but a simple necessity."
    Niklaus E. Wirth


    Rate any post that helped you, it's a good way of saying thanks
    Please specify your Visual Studio Version!

    Why rating is useful

    My Code Bank Submissions: How to determine Windows Version| Working With Mouse Events | Blocking Input Using API | Get host's IP | Minimize to system tray "animated" | Colored ListBox (custom fonts, colors, highlight) Updated -New Class! | [VS 2008] Strong encryption and hashing class - Updated! 31/August/2009 | Create a shortcut using IWshRuntimeLibrary

  12. #12

  13. #13
    Fanatic Member
    Join Date
    Oct 2008
    Location
    Dominican Republic
    Posts
    733

    Re: [WIP] Customizable ProgressBar



    When I typed the code you gave me, the tooltip on the the New() keyword said: 'Public Sub New()' in designer generated type 'App.ProgressBarEx' should call InitializeComponent method. I don't know what to do with that.
    Last edited by tassa; Sep 30th, 2009 at 04:46 PM.
    "In our profession, precision and perfection are not a dispensable luxury, but a simple necessity."
    Niklaus E. Wirth


    Rate any post that helped you, it's a good way of saying thanks
    Please specify your Visual Studio Version!

    Why rating is useful

    My Code Bank Submissions: How to determine Windows Version| Working With Mouse Events | Blocking Input Using API | Get host's IP | Minimize to system tray "animated" | Colored ListBox (custom fonts, colors, highlight) Updated -New Class! | [VS 2008] Strong encryption and hashing class - Updated! 31/August/2009 | Create a shortcut using IWshRuntimeLibrary

  14. #14

    Thread Starter
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Re: [WIP] Customizable ProgressBar

    For the drawing, as I said before, the control is supposed to be used by handling the PaintProcess method and drawing in there. But you can do the drawing in the UserControl code too if you want I suppose. Anyway, you should not use Me.Bounds for the brush rectangle. You should either use 'rect', or Me.ClientRectangle, depending on your need. Using 'rect' will draw the gradient from full red on the left side, to full white on the right side of the progress 'fill', no matter how much the value is. Using ClientRectangle will draw it from full red on the left side, to full white on the right side of the entire progressbar. The difference is hard to explain in words but you'll get the idea if you try both. With ClientRectangle, the gradient is fixed, while with 'rect', the gradient is 'elongated' when the value changes.


    For the warning you get, it tells you exactly what you need to do:
    The constructor (Public Sub New) should call the InitializeComponent method. So add a call to the InitializeComponent method.

  15. #15
    Fanatic Member
    Join Date
    Oct 2008
    Location
    Dominican Republic
    Posts
    733

    Re: [WIP] Customizable ProgressBar

    If I use 'rect', it throws this exception Rectangle '{X=0,Y=0,Width=0,Height=20}' cannot have a width or height equal to 0.

    For the InitializeComponent sub, should it be like this: (I've never used it, that's why I ask)

    vb.net Code:
    1. Private Sub InitializeComponent()
    2.    Me.SetStyles(ControlStyles.AllPaintingInWmPaint, True)
    3.    Me.SetStyles(ControlStyles.ResizeRedraw, True)
    4.    Me.SetStyles(ControlStyles.UserPaint, True)
    5.    Me.SetStyles(ControlStyles.DoubleBuffer, True)
    6. End Sub

    When I type it it gives me this error: Error 1 'Private Sub InitializeComponent()' has multiple definitions with identical signatures.

    Thanks a lot for your help .
    "In our profession, precision and perfection are not a dispensable luxury, but a simple necessity."
    Niklaus E. Wirth


    Rate any post that helped you, it's a good way of saying thanks
    Please specify your Visual Studio Version!

    Why rating is useful

    My Code Bank Submissions: How to determine Windows Version| Working With Mouse Events | Blocking Input Using API | Get host's IP | Minimize to system tray "animated" | Colored ListBox (custom fonts, colors, highlight) Updated -New Class! | [VS 2008] Strong encryption and hashing class - Updated! 31/August/2009 | Create a shortcut using IWshRuntimeLibrary

  16. #16

    Thread Starter
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Re: [WIP] Customizable ProgressBar

    For the Rectangle error, that's odd. I don't get that error even when the rectangle is 0,0,0,48.

    For the InitializeComponent, you don't create a method called InitializeComponent, you only need to call it. It already exists, in the hidden Designer code. It is the method that sets up the Form (or in this case UserControl) by adding the controls and setting their properties. In this case, it doesn't do much, but you should still call it in the constructor:
    Code:
          Public Sub New()
             InitializeComponent()
    
             Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
             Me.SetStyle(ControlStyles.ResizeRedraw, True)
             Me.SetStyle(ControlStyles.UserPaint, True)
             Me.SetStyle(ControlStyles.DoubleBuffer, True)
          End Sub
    Usually, if you just type "Public Sub New" and press enter, VS will autocomplete it to something like this:
    Code:
        Public Sub New()
    
            ' This call is required by the Windows Form Designer.
            InitializeComponent()
    
            ' Add any initialization after the InitializeComponent() call.
    
        End Sub
    You just need to add your own code beneath the last comment.


    ----
    This may be a little confusing, so let me explain what actually happens. If you add a new Form to your project, it's code will be blank, right? But, the code you see is not the only code, there is also the Designer code.

    If you add a Button to your form, for example, the only reason VS knows how and where to draw your button, and with which properties, is because that information is stored in the Designer file, as you can see if you look closely:
    vb.net Code:
    1. <Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
    2. Partial Class Form1
    3.     Inherits System.Windows.Forms.Form
    4.  
    5.     'Form overrides dispose to clean up the component list.
    6.     <System.Diagnostics.DebuggerNonUserCode()> _
    7.     Protected Overrides Sub Dispose(ByVal disposing As Boolean)
    8.         Try
    9.             If disposing AndAlso components IsNot Nothing Then
    10.                 components.Dispose()
    11.             End If
    12.         Finally
    13.             MyBase.Dispose(disposing)
    14.         End Try
    15.     End Sub
    16.  
    17.     'Required by the Windows Form Designer
    18.     Private components As System.ComponentModel.IContainer
    19.  
    20.     'NOTE: The following procedure is required by the Windows Form Designer
    21.     'It can be modified using the Windows Form Designer.  
    22.     'Do not modify it using the code editor.
    23.     <System.Diagnostics.DebuggerStepThrough()> _
    24.     Private Sub InitializeComponent()
    25.         Me.Button1 = New System.Windows.Forms.Button
    26.         Me.SuspendLayout()
    27.         '
    28.         'Button1
    29.         '
    30.         Me.Button1.Location = New System.Drawing.Point(127, 78)
    31.         Me.Button1.Name = "Button1"
    32.         Me.Button1.Size = New System.Drawing.Size(75, 23)
    33.         Me.Button1.TabIndex = 0
    34.         Me.Button1.Text = "Button1"
    35.         Me.Button1.UseVisualStyleBackColor = True
    36.         '
    37.         'Form1
    38.         '
    39.         Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
    40.         Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
    41.         Me.ClientSize = New System.Drawing.Size(284, 262)
    42.         Me.Controls.Add(Me.Button1)
    43.         Me.Name = "Form1"
    44.         Me.Text = "Form1"
    45.         Me.ResumeLayout(False)
    46.  
    47.     End Sub
    48.     Friend WithEvents Button1 As System.Windows.Forms.Button
    49. End Class

    Here, you see the InitializeComponent method, doing its job by setting the form and control properties. Now, there is always a so called default constructor, which I believe in this case automatically calls the InitializeComponent method. Otherwise, your controls and form properties would be lost when you run your application, as the InitializeComponent method was never called.

    But, once you add your own constructor, by adding the Public Sub New 'method' in the usual code file, the default constructor is no longer used, and there is a risk that the InitializeComponent method is never called!

    You can even try that. Add a Public Sub New, and leave out the InitializeComponent call. The result when you run the application will be a completely blank form, default size, no text, etc. The controls are never added!

    So, in short, if you create your own constructor in a Form or UserControl, you should always call the InitializeComponent method before you do anything else.

  17. #17
    Fanatic Member
    Join Date
    Oct 2008
    Location
    Dominican Republic
    Posts
    733

    Re: [WIP] Customizable ProgressBar

    Thanks Nick! . This works perfectly now! And thanks for that explanation!
    "In our profession, precision and perfection are not a dispensable luxury, but a simple necessity."
    Niklaus E. Wirth


    Rate any post that helped you, it's a good way of saying thanks
    Please specify your Visual Studio Version!

    Why rating is useful

    My Code Bank Submissions: How to determine Windows Version| Working With Mouse Events | Blocking Input Using API | Get host's IP | Minimize to system tray "animated" | Colored ListBox (custom fonts, colors, highlight) Updated -New Class! | [VS 2008] Strong encryption and hashing class - Updated! 31/August/2009 | Create a shortcut using IWshRuntimeLibrary

  18. #18

    Re: [WIP] Customizable ProgressBar

    Got a little problem here when using the progressbar.
    I used your example for the gradient (the dark blue to light blue.) but instead of it painting like i thought it would....I get this:


    Not really sure what's going on....any help would be great.

    I set these in the form load: (also tried without them)
    vb.net Code:
    1. Private Sub solaris_Startup_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    2.         Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
    3.         Me.SetStyle(ControlStyles.ResizeRedraw, True)
    4.         Me.SetStyle(ControlStyles.UserPaint, True)
    5.         Me.SetStyle(ControlStyles.DoubleBuffer, True)
    6.     End Sub

    I'm animating it as a test with a Timer changing it's value every second. (I even disabled it as a test and still got the same weird looking error).

    I did temporarily fix it (or so I thought) by declaring it New in the code. It didn't increment. I added InitializeComponent(), which messed with my form a bit but fixed the bar. Still didn't increment. Any suggestions?

  19. #19

    Thread Starter
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Re: [WIP] Customizable ProgressBar

    That cross looks like there was an error or something. Try adding some Try/Catch blocks in your painting events.

    Also, setting the style of the form has nothing to do with the style of any controls on that form, so that won't change anything.

    I also don't understand much of your last line. Can you elaborate? Show some code?

  20. #20

    Re: [WIP] Customizable ProgressBar

    I incremented like this:
    vb.net Code:
    1. Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    2.         If ProgressbarEx1.Value < 100 Then ProgressbarEx1.Increment(1) Else ProgressbarEx1.Value = 0
    3.     End Sub
    The timer has an interval of 1000, which is roughly 1 second.

    I put the Try/Catch statement in the paint event and got this error:
    Code:
    System.ArgumentException: Rectangle '{X=0,Y=0,Width=0,Height=22}' cannot have a width or height equal to 0.
    
       at System.Drawing.Drawing2D.LinearGradientBrush..ctor(Rectangle rect, Color color1, Color color2, LinearGradientMode linearGradientMode)
    
       at RMXP_Pool.solaris_Startup.ProgressBarEx1_PaintProcess(Object sender, ProgressBarProcessPaintEventArgs e) in C:\Users\formlesstree\Documents\Visual Studio 2008\Projects\RMXP Scrive\RMXP Scrive\Skins\Solaris Skin\Forms\solaris_Startup.vb:line 34
    Could it be that when the gradient is being painted, that the error is thrown because the width is zero (aka the bar has no value)? Any other time it looks to be OK...
    EDIT: added this to the Paint area:
    vb.net Code:
    1. If ProgressbarEx1.Value = 0 Then Exit Sub
    No more errors

  21. #21

  22. #22
    Lively Member
    Join Date
    Nov 2009
    Posts
    76

    Re: [WIP] Customizable ProgressBar


  23. #23
    Junior Member
    Join Date
    Mar 2010
    Posts
    19

    Re: [WIP] Customizable ProgressBar

    I Don't Understand how to use this code..
    CAn you Help me?
    I put the region ecc, to a new ControlUser, called xxxxxx
    But my progress bar don't color..

  24. #24

    Thread Starter
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Re: [WIP] Customizable ProgressBar

    Just add a new UserControl, replace the code with the code in my second post, and build your solution/project. Then the new control should appear in the toolbox and you can drag it to your form.

    If you want different colors then the default (green I think) you need to handle the PaintBackground and PaintProcess events, in which you do the drawing yourself. See my examples.

  25. #25
    Junior Member
    Join Date
    Mar 2010
    Posts
    19

    Re: [WIP] Customizable ProgressBar

    Don't Work,,
    I Create ControlUser, ProgressBarEx, paste you second Source, and now?

  26. #26
    Junior Member
    Join Date
    Mar 2010
    Posts
    19

    Re: [WIP] Customizable ProgressBar

    O Work Prefeclty
    TNK!!!!

  27. #27
    Junior Member
    Join Date
    Mar 2010
    Posts
    19

    Re: [WIP] Customizable ProgressBar

    i have two erro:

    Errore 1 Tipo 'ProgressBarEx.ProgressBarEx.ProgressBarProcessPaintEventArgs' non definito. H:\Documents and Settings\Sh0tAll\Impostazioni locali\Dati applicazioni\Temporary Projects\WindowsApplication1\Form1.vb 20 87 WindowsApplication1
    Errore 2 Il metodo 'Private Sub ProgressBarEx1_PaintProcess(sender As Object, e As <tipo non riconosciuto>)' non pu&#242; gestire l'evento 'Public Event PaintProcess(sender As Object, e As WindowsApplication1.ProgressBarEx.ProgressBarProcessPaintEventArgs)' perch&#233; non ha una firma compatibile. H:\Documents and Settings\Sh0tAll\Impostazioni locali\Dati applicazioni\Temporary Projects\WindowsApplication1\Form1.vb 20 172 WindowsApplication1

  28. #28
    PowerPoster JuggaloBrotha's Avatar
    Join Date
    Sep 2005
    Location
    Lansing, MI; USA
    Posts
    4,286

    Re: [WIP] Customizable ProgressBar

    I'm not fluent in your native language, but from what I can gather you have 2 build errors, both are in the control's Paint event, can you post your paint event code?
    Currently using VS 2015 Enterprise on Win10 Enterprise x64.

    CodeBank: All ThreadsColors ComboBoxFading & Gradient FormMoveItemListBox/MoveItemListViewMultilineListBoxMenuButtonToolStripCheckBoxStart with Windows

  29. #29
    Junior Member
    Join Date
    Mar 2010
    Posts
    19

    Re: [WIP] Customizable ProgressBar

    i Have This Code :
    Code:
    Public Class Form1
    
        Private Sub ProgressBarEx1_PaintProcess(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ProgressBarEx1.Load
    
            Using b As New Drawing2D.LinearGradientBrush(e.Bounds, Color.DarkBlue, Color.LightBlue, Drawing2D.LinearGradientMode.Horizontal)e.Graphics.FillRectangle(b, e.Bounds)
    
            End Using
        End Sub
    End Class
    Why Give me Vb this 2 Error?:

    Code:
    Errore	1	'Bounds' non è un membro di 'System.EventArgs'.	H:\Documents and Settings\Sh0tAll\Impostazioni locali\Dati applicazioni\Temporary Projects\ProgressX\Form1.vb	5	54	ProgressX
    Errore	2	Prevista fine dell'istruzione.	H:\Documents and Settings\Sh0tAll\Impostazioni locali\Dati applicazioni\Temporary Projects\ProgressX\Form1.vb	5	137	ProgressX

  30. #30

    Thread Starter
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Re: [WIP] Customizable ProgressBar

    That method is handling the Load event of the progressbar, not the PaintProcess event. Simply changing the name of the method (which you must have done) to PaintProcess does not make it handle a different event. Instead, you need to change the part after the Handles statement. Or, you could select the control in the designer, view the events list (near the properties list, there's a lightning bolt icon button, click that) and select the appropriate event.

  31. #31
    Junior Member
    Join Date
    Mar 2010
    Posts
    19

    Re: [WIP] Customizable ProgressBar

    1 Second..
    Can you Edit my source, and post?

  32. #32

    Thread Starter
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Re: [WIP] Customizable ProgressBar

    How about I explain where you went wrong, so you can fix it yourself?

    Event handlers work basically like this:
    Code:
    Private Sub <Method Name>(ByVal sender As Object, ByVal e As <??>EventArgs) Handles <Event>
    The last part, <Event>, is the most important. This is what determines which event is handled, not the name of the method. Examples for <Event> are "Button1.Click", "TextBox1.TextChanged", and in your case, "ProgressBarEx1.PaintProcess".
    The <Method Name> is just the name of the method and bears no importance. By default, when the event handler code is automatically generated, it is given a name that reflects the event (such as "Button1_Click" or "ProgressBarEx1_PaintProcess", but that is completely arbitrary, you can name the methods whatever you like.

    Finally, the <??> part before the EventArgs determine which type of event arguments the event has. For many events, <??> is nothing and e is just of type EventArgs. For a KeyPress event, for example, the e is of type KeyPressEventArgs instead. For my control and its PaintProcess event, the e should be of type ProgressBarProcessPaintEventArgs.


    So, where did you go wrong? You probably doubleclicked the control, which automatically inserts the default event handler, which in this case is the Load event (which it is by default, perhaps I should have chosen a different one, but it doesn't really matter). You then probably thought "I don't want the Load event, I want the PaintProcess event", and changed the name of the method, which as I said is irrelevant. You did not change the actual event that the method handled, so it does not work.

    To fix, all you need to do is remove the method. Then go back to the designer and let it insert the correct event handler code automatically. You can select the control, then click the lightning bolt icon on the properties list window, which will show the events list. Scroll down until you find the PaintProcess event, and doubleclick it. Then, the correct method will be inserted, with the correct Handles clause, and the correct type of EventArgs (e).

  33. #33
    Junior Member
    Join Date
    Mar 2010
    Posts
    19

    Re: [WIP] Customizable ProgressBar

    CAn you give my you Contact of Messenger?

  34. #34

  35. #35
    Junior Member
    Join Date
    Mar 2010
    Posts
    19

    Re: [WIP] Customizable ProgressBar

    For, help me with Team Viewer, Beacuse Im Itailan, i not Understand very well English!

  36. #36

    Thread Starter
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Re: [WIP] Customizable ProgressBar

    I'm afraid I really don't have time for that.

    The correct code you were looking for is:
    Code:
    Private Sub ProgressBarEx1_PaintProcess(ByVal sender As System.Object, ByVal e As ProgressBarProcessPaintEventArgs) Handles ProgressBarEx1.PaintProcess
    
            Using b As New Drawing2D.LinearGradientBrush(e.Bounds, Color.DarkBlue, Color.LightBlue, Drawing2D.LinearGradientMode.Horizontal)e.Graphics.FillRectangle(b, e.Bounds)
    
            End Using
        End Sub

  37. #37
    Junior Member
    Join Date
    Mar 2010
    Posts
    19

    Re: [WIP] Customizable ProgressBar

    Dont' Work &#231;_&#231;

    Can give me a Complete Proget?

  38. #38

    Thread Starter
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Re: [WIP] Customizable ProgressBar

    Why is it not working? Perhaps you need to replace ProgressBarProcessPaintEventArgs with ProgressBarEx.ProgressBarEx.ProgressBarProcessPaintEventArgs, as in my example in the first post.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width