Page 1 of 2 12 LastLast
Results 1 to 40 of 43

Thread: [RESOLVED] Need help with DrawEllipse() and Me.Refresh() and Label1.text

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2014
    Posts
    313

    Resolved [RESOLVED] Need help with DrawEllipse() and Me.Refresh() and Label1.text

    I want to draw 1000 random circles.
    During the loop, I also want to update a label to display a counter.

    If I do Me.Refresh() in the loop, all the drawing is lost.

    What is the correct way?


    Code:
    Public Class Form1
        Public myPen As Pen
        Public myGraphics As Graphics
        Public generator As New Random
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            myPen = New Pen(Drawing.Color.Black, 1)
            myGraphics = Me.CreateGraphics
        End Sub
    
        Private Sub Form1_MouseDown(sender As Object, e As MouseEventArgs) Handles Me.MouseDown
    
            Dim x As Integer
            Dim y As Integer
    
            For i = 1 To 1000
                x = generator.Next(0, 100)
                y = generator.Next(0, 100)
    
                myGraphics.DrawEllipse(myPen, x, y, 1, 1)
    
                'This displays the count.
                'Alone, it does not update until the 1000 loop is done
                Label1.Text = i
    
                'This forces the label refresh, but all circles are lost.
                'Me.Refresh()
    
            Next
    
        End Sub
    End Class

  2. #2
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,989

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    That's because you are not doing the drawing in the Paint event of the form. Refresh will force a paint, and that wipes out what you have done. Do all drawing in the Paint event, not in Load or MouseDown. Also, don't create a graphics object, because the e argument of the Paint event supplies one for you.
    My usual boring signature: Nothing

  3. #3

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2014
    Posts
    313

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    Where is the graphics object supplied?

    Code:
    Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint

  4. #4

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2014
    Posts
    313

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    The code does not seem to work as desired in Paint()
    If I draw 1000 circles in Paint() and update the label, I think that triggers the Paint() event, so it gets stuck in a forever loop.
    Paint() does not seem like the correct place, exactly

  5. #5
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,299

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    The Paint event works exactly as it should. If your code doesn't work then it's your code that is wrong but you haven't shown us your code so we have to guess what might be wrong with it. If you just copied and pasted the code you already have then you will be calling Refresh in the Paint event handler, which is obviously wrong and you should have seen that for yourself if you had thought through the logic. If that's not the issue then that's a perfect example of why you shouldn't make us guess what code you're using. Just assume that you should ALWAYS show us the relevant code and then you won't make the mistake of not doing so when you should.

    The point of the Refresh method is to force the control to raise a Paint event. Why would you want to force a Paint event at the end of the Paint event handler? You wouldn't, so why would you call that method? The drawing gets done in the Paint event handler so you would call Refresh whenever you want to change the drawing, e.g. if the user clicks and drags to draw an ellipse then you would call Refresh when they release the mouse button. The data representing the drawing in one or more fields and you should call Refresh any time that data is changed. The new data is then read in the Paint event handler and the new drawing done.

    That said, you really shouldn't be calling Refresh anyway. Refresh calls Invalidate without an argument and then calls Update, which means that the control is completely redrawn immediately. Instead, you should calculate the smallest area you can that has or may have changed and pass that as an argument to Invalidate and leave it at that. That means that only that area of the control will be repainted and it will be done when the UI thread is next free to do so. There's generally no need to force an immediate repaint because one is scheduled when you call Invalidate and it will happen almost immediately anyway. Also, it is the actually painting of pixels to the screen that is time-consuming, not the drawing, so that part should be kept to a minimum. It is excessive painting that causes the flicker that we sometimes see in WinForms. You can follow the CodeBank link in my signature below and check out some of my Drawing threads for examples.

  6. #6
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,464

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    First, the way you’ve been told to do your drawing is the correct way, but the Paint event doesn’t just draw once. It’ll draw a 1000 new random ellipses every time it runs.

    To update the label, refresh the label, not the form...

    Code:
    Label1.Refresh
    If you want to persist the first 1000 random ellipses...

    Code:
    Public Class Form1
        Private myPen As Pen
        Private myGraphics As Graphics
        Private generator As New Random
        Private img as BitMap = Nothing
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            myPen = New Pen(Drawing.Color.Black, 1)
            
        End Sub
    
        Private Sub Form1_MouseDown(sender As Object, e As MouseEventArgs) Handles Me.MouseDown
            img = New BitMap(Me.Width, Me.Height)
            Dim gr As Graphics = Graphics.FromImage(img)
            Dim x As Integer
            Dim y As Integer
    
            For i = 1 To 1000
                x = generator.Next(0, 100)
                y = generator.Next(0, 100)
    
                gr.DrawEllipse(myPen, x, y, 1, 1)
    
                'This displays the count.
                'Alone, it does not update until the 1000 loop is done
                Label1.Text = i
    
                'This forces the label refresh, but all circles are lost.
                Label1.Refresh()
    
            Next
    
            Me. Refresh
        End Sub
    
        Public Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
            If Not img Is Nothing
                e.Graphics.DrawImage(img, Point.Empty)
            End If
        End Sub
    
    End Class

  7. #7

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2014
    Posts
    313

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    That worked.
    I moved the loop into Paint()
    I then did Label1.refresh() inside the loop
    That got the real time counter refreshing.
    Thanks!

  8. #8
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,464

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    You should make a note of what I said about the Form Paint event. It’ll draw a new image every time it runs. Try minimising and restoring your Form

  9. #9
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,299

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    Updating the Label while you draw the ellipses in a loop is a very bad idea too. That loop should execute so quickly that you shouldn't really be able to see any single number in the Label anyway. If you want it to happen slowly enough that the user can actually make out the number of ellipses then you should not be using a loop. Instead, you could use a Timer and just add one ellipse at a time and draw them all every time, e.g.
    vb.net Code:
    1. 'Random number generator.
    2. Private rng As New Random
    3.  
    4. 'Bounding boxes for ellipses.
    5. Private boxes As New List(Of Rectangle)
    6.  
    7. Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
    8.     Timer1.Start()
    9. End Sub
    10.  
    11. Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    12.     'Create a new bounding box.
    13.     Dim box As New Rectangle(rng.Next(PictureBox1.Width),
    14.                              rng.Next(PictureBox1.Height),
    15.                              1,
    16.                              1)
    17.  
    18.     boxes.Add(box)
    19.  
    20.     Dim boxCount = boxes.Count
    21.  
    22.     'Stop at 1000 ellipses.
    23.     If boxCount = 1000 Then
    24.         Timer1.Stop()
    25.     End If
    26.  
    27.     'The area that is invalidated must be one pixel greater that the area that has changed in both directions.
    28.     'Inflating the bounding box we created by one pixel in both directions is the easiest way to do this.
    29.     'This will include an extra pixel at the top and on the left but that's no big deal.
    30.     box.Inflate(1, 1)
    31.  
    32.     'Flag the changed area as needing to be repainted.
    33.     PictureBox1.Invalidate(box)
    34.  
    35.     'Display the new ellipse count.
    36.     Label1.Text = boxCount.ToString()
    37. End Sub
    38.  
    39. Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
    40.     'We do the drawing and then the system does the painting.
    41.     'We draw everything every time and then the system paints only the area that was invalidated.
    42.     For Each box As Rectangle In boxes
    43.         e.Graphics.DrawEllipse(Pens.Black, box)
    44.     Next
    45. End Sub

  10. #10
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,989

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    I don't totally agree with that...but having re-read the preceding points, I have no idea what the objective is. I can't see any scenario where post #7 makes any useful sense. Paint shouldn't be used that way, but since we don't know what the objective is, I guess it can work that way as well as any other way.
    My usual boring signature: Nothing

  11. #11

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2014
    Posts
    313

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    Quote Originally Posted by .paul. View Post
    You should make a note of what I said about the Form Paint event. It’ll draw a new image every time it runs. Try minimising and restoring your Form

    Right, is that why you drew on the Bitmap ?

  12. #12
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,989

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    I think you need to explain what your objective is.

    The Paint event is raised in all kinds of different situations. Anytime Windows decides that something needs to be redrawn. If you are creating all those random ellipses in the Paint event, then you'll get random ellipses being drawn at kind of unpredictable times. It's hard to conceive of a situation where that makes sense. They'll also all be created super fast, since most of the code in that loop will take less than a millisecond (the screen won't be updating anywhere near that fast), so only that label refresh would be slow enough to see. Without the label, the ellipses will all be created and drawn all at once, since a 60Hz screen will only redraw the screen once every 17ms, or so, while all the ellipses can be created in less than 1 ms.

    So, what's the point? You'd end up with a different set of random ellipses every time the Paint event was fired, and you can't totally predict that. It IS predictable, but you can trigger it by accident, too, which doesn't seem likely to meet your goals.
    My usual boring signature: Nothing

  13. #13

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2014
    Posts
    313

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    Yea, that is why I tried to do the drawing code outside of the Paint() event.

    From what I've gathered, it seems like the best way to create persistent drawings is
    1) using Paint(), if the drawing is static and redraw is ok.
    2) draw on Bitmap, if redraw is not ok.

  14. #14
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,989

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    What I would do is create the ellipses to a List(of Ellipse). That can be done either on load, or on a button click, depending on what you want to have happen. I'd use the button if I wanted the form to start blank, and I'd use the load if I only wanted to create one set. I'd use both the button and the load if I wanted the form to start with ellipses, but also to be able to generate a new set when I wanted to.

    It's the next step that I'm not sure about, and that has to do with the label. Creating those ellipses will be so fast as to take no apparent time. If you want them to show up one after another, then I'd put a timer on the form, because I'd be wanting to slow down their creation far enough that the result would be pleasing to the eye, whatever you feel that to be. For example, you might set the timer to have an interval of 100 if you want the ellipses to appear rapidly, or as slow as 1000 if you wanted one per second.

    So, a timer if you want them to show up slowly, no timer (and no label) if you want them to show up instantly. If you use the timer, then there is no loop. You'd be starting the timer in the load event, and if you have a button to rebuild the ellipse collection, then in the button you'd:

    1) clear the collection of ellipses.
    2) invalidate the form with Me.Invalidate
    3) start the timer.

    In the timer, you'd create one ellipse and add it to the collection, then invalidate the form.

    In the Paint event, you'd draw whatever was in the collection of ellipses.
    My usual boring signature: Nothing

  15. #15
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,464

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    Quote Originally Posted by RipVoidWinkle View Post
    Right, is that why you drew on the Bitmap ?
    Yes. I drew the bitmap once, and any subsequent repaints of the form would draw that bitmap on the form, until next time you trigger the code that draws the bitmap

  16. #16

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2014
    Posts
    313

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    Shaggy, let me take another look this week.
    Maybe I will not directly draw, but create a collection of ellipses that can be re-rendered consistently.
    Like the Paint() just draws the list of Ellipses, and some other button or event loads the list, in a loop.

  17. #17
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,464

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    Quote Originally Posted by RipVoidWinkle View Post
    Paint() just draws the list of Ellipses, and some other button or event loads the list
    That'll work

  18. #18
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,299

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    Quote Originally Posted by RipVoidWinkle View Post
    Shaggy, let me take another look this week.
    Maybe I will not directly draw, but create a collection of ellipses that can be re-rendered consistently.
    Like the Paint() just draws the list of Ellipses, and some other button or event loads the list, in a loop.
    You mean exactly what I did in post #9?

    There is no such thing as an Ellipse, unless you define it yourself. Given that the DrawEllipse method takes a Rectangle as an argument, storing Rectangles seems a logical choice, just as I did in post #9.

  19. #19

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2014
    Posts
    313

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    Weird, I don't know how I missed post #9.
    Thanks for that. I will try this today.

  20. #20
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,989

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    Yeah, it is weird. I missed the meat of post #9, as well. I ended up suggesting (without any code) a very similar approach. I did think that somebody had posted that solution, but when I looked back, I saw what .Paul. had posted in #6, which didn't include a timer. I missed #9, which DID include a timer.

    I think JMC, and his posts, were temporarily abducted by aliens with very strange hair such that his posts couldn't be read by the general public.
    My usual boring signature: Nothing

  21. #21
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,464

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    Quote Originally Posted by Shaggy Hiker View Post
    Yeah, it is weird. I missed the meat of post #9, as well... I think JMC, and his posts, were temporarily abducted by aliens with very strange hair such that his posts couldn't be read by the general public.
    There was talk of a ransom, but they abandoned that idea after being with him for 10 minutes...

  22. #22
    Fanatic Member Delaney's Avatar
    Join Date
    Nov 2019
    Location
    Paris, France
    Posts
    845

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    Quote Originally Posted by Shaggy Hiker View Post

    I think JMC, and his posts, were temporarily abducted by aliens with very strange hair such that his posts couldn't be read by the general public.
    Why "with very strange hair" ?
    The best friend of any programmer is a search engine
    "Don't wish it was easier, wish you were better. Don't wish for less problems, wish for more skills. Don't wish for less challenges, wish for more wisdom" (J. Rohn)
    “They did not know it was impossible so they did it” (Mark Twain)

  23. #23
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,299

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    Quote Originally Posted by .paul. View Post
    There was talk of a ransom, but they abandoned that idea after being with him for 10 minutes...
    They lasted longer than most.

  24. #24

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2014
    Posts
    313

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    I rewrote my program.

    In the formLoad, I created a bunch of Rectangles, and added them to a List.
    in the Paint(), I drawEllipses for each Rect in the list.
    This solved the persistence issue and no longer regenerates the dots for every Paint() invocation.

    However, the timer idea does not work.
    I add a new circle to the list in each tick(), but then the dog tries to catch his own tail.
    After there are a certain number of circles are in the list, the Paint() can't keep up with the new timer tick() and refresh/invalidate is fired from the next tick() before all the circles are repainted.
    So, at some point, the paint() never catches up, and starts to glitch, and can never finish the list

    Therefore, ditched the timer, and not use me.refresh() or me.invalidate() for every new circle.

    I think the other method was correct,
    where I generated all circles into a List on form Load,
    and then used Paint() to iterate through the list .

    To slow down the generating animation, I call Threading.Thread.Sleep(1) in the Paint()
    To give the user a real time Label update, I just call label.refresh() in the Paint()

    This seems to be the best way to generate circles, slowly, while displaying a real-time count label.


    The only glitch is that once the 100 circles are drawn, the label still keeps updating itself, flashing.
    I think in Paint(), Label.Refresh() must trigger Paint() and create an infinite loop ?
    Last edited by RipVoidWinkle; Feb 1st, 2021 at 07:55 PM.

  25. #25

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2014
    Posts
    313

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    The other weird glitch is that I can only trigger the makeCircle() loop in FormLoad() Adding rectangles to the List
    When I Start the program, the circles are already drawing.

    If I try to create the circle List in MouseUp or MouseDown, nothing happens.

  26. #26
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,464

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    Nope. Paint fires regularly. The reason your label keeps updating is because you haven’t enclosed it in any conditional statements. Your ellipses start at 1 and end at 100... That’s conditional. An If statement is also a conditional. Your Paint event doesn’t just stop firing because you’re not requesting a repaint.

  27. #27
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,464

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    Start the drawing in the Form_Shown event

  28. #28
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,464

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    If you only want to draw your ellipses on mousedown, show us your code that doesn’t work. Include all relevant parts, i.e. variable declarations, mousedown event, paint event...

  29. #29
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,299

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    GDI+ drawing works quite simply and I think I've already explained it here but I'll try again.

    Firstly, declare one or more fields to store the data represents your drawing. If you want to draw ellipse shapes then the logical data storage is a List(Of Rectangle) because an ellipse is defined by its bounding box and a collection can store zero, one or more items.

    Secondly, handle the Paint event of the control you want to draw on and, in the event handler, read the data from the field(s) and draw based on that. If you want to draw ellipses then the logical option is to loop through the List(Of Rectangle) and call DrawEllipse for each one. It is important to note that you ALWAYS draw EVERYTHING in the Paint event handler. The Paint event can be raised at any time and you want to reinstate your entire drawing EVERY time it is raised. For instance, if the form gets minimised and restored, it will be completely repainted so you want your entire drawing reinstated.

    Finally, whenever the drawing needs to change, you modify the field(s) storing the drawing data appropriately and then you call Invalidate on the control to prompt a Paint event. If you don't pass an argument to Invalidate then the entire control will be repainted and that is slow. For that reason, you should calculate the area that has or may have changed and specify that area when calling Invalidate. If you are adding a new ellipse then you already have a Rectangle that describes the area in occupies so that Rectangle is what you should pass to Invalidate. That way, even though the drawing code draws everything, only the part within that area will be repainted with the result of that drawing, thus keeping the slow part to a minimum.

    So, let's say that you want the user to be able to press the mouse button, drag and release to draw an ellipse. You can take the easy option and wait until they release to draw the new ellipse, in which case you don't add the Rectangle to the list and call Invalidate until MouseUp. You can also take the more difficult option of drawing the ellipse as they drag the mouse. In that case, you would add the Rectangle to the list immediately and keep changing its value and calling Invalidate on MouseMove. You would need to use an additional Boolean field to indicate whether you were dragging or not.

  30. #30

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2014
    Posts
    313

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    Quote Originally Posted by .paul. View Post
    Nope. Paint fires regularly. The reason your label keeps updating is because you haven’t enclosed it in any conditional statements. Your ellipses start at 1 and end at 100... That’s conditional. An If statement is also a conditional. Your Paint event doesn’t just stop firing because you’re not requesting a repaint.
    I update the label.text and call label.refresh within the "for each" ellipse loop in Paint()

  31. #31

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2014
    Posts
    313

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    Quote Originally Posted by jmcilhinney View Post
    GDI+ drawing works quite simply and I think I've already explained it here but I'll try again.

    Firstly, declare one or more fields to store the data represents your drawing. If you want to draw ellipse shapes then the logical data storage is a List(Of Rectangle) because an ellipse is defined by its bounding box and a collection can store zero, one or more items.

    Secondly, handle the Paint event of the control you want to draw on and, in the event handler, read the data from the field(s) and draw based on that. If you want to draw ellipses then the logical option is to loop through the List(Of Rectangle) and call DrawEllipse for each one. It is important to note that you ALWAYS draw EVERYTHING in the Paint event handler. The Paint event can be raised at any time and you want to reinstate your entire drawing EVERY time it is raised. For instance, if the form gets minimised and restored, it will be completely repainted so you want your entire drawing reinstated.

    Finally, whenever the drawing needs to change, you modify the field(s) storing the drawing data appropriately and then you call Invalidate on the control to prompt a Paint event. If you don't pass an argument to Invalidate then the entire control will be repainted and that is slow. For that reason, you should calculate the area that has or may have changed and specify that area when calling Invalidate. If you are adding a new ellipse then you already have a Rectangle that describes the area in occupies so that Rectangle is what you should pass to Invalidate. That way, even though the drawing code draws everything, only the part within that area will be repainted with the result of that drawing, thus keeping the slow part to a minimum.

    So, let's say that you want the user to be able to press the mouse button, drag and release to draw an ellipse. You can take the easy option and wait until they release to draw the new ellipse, in which case you don't add the Rectangle to the list and call Invalidate until MouseUp. You can also take the more difficult option of drawing the ellipse as they drag the mouse. In that case, you would add the Rectangle to the list immediately and keep changing its value and calling Invalidate on MouseMove. You would need to use an additional Boolean field to indicate whether you were dragging or not.
    Yup, I did all of that.
    Except I didn't need to call Invalidate.

    I load the rect List on Form_Load()
    Then the Paint() renders all the ellipses using the list.
    Works.

    The only remaining issue is the label is flickering and constantly refreshing itself
    Maybe the Paint() is constantly being called, even after all the circles are done drawing.
    So, the circles appear static, while the label keeps flashing. I can live with that.

  32. #32
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,299

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    Quote Originally Posted by RipVoidWinkle View Post
    Except I didn't need to call Invalidate.

    I load the rect List on Form_Load()
    Then the Paint() renders all the ellipses using the list.
    Works.
    The Load event is raised before the form is displayed for the first time, so the Paint event is always going to be raised after that, when the for IS displayed for the first time.

  33. #33
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,299

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    Quote Originally Posted by RipVoidWinkle View Post
    I update the label.text and call label.refresh within the "for each" ellipse loop in Paint()
    Nope. That is absolutely wrong. As has already been stated, the Paint event can be raised repeatedly and at times you wouldn't expect, and may not cause a repaint of the whole form/control either. What possible reason could you have for wanting the Label to show the incrementing count of ellipses drawn every single time the Paint event is raised? That's madness!

    What is this Label actually supposed to represent? If it's the ellipses being added to the list in the first place then you only do that once and you do it before the form is displayed anyway, so what sane use is that Label? If you want the user to actually see the ellipses being added and see the Label increment accordingly then I've already shown you how that can be done. Basically, you're doing something bad for a misguided reason.

  34. #34

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2014
    Posts
    313

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    Quote Originally Posted by jmcilhinney View Post
    Nope. That is absolutely wrong. As has already been stated, the Paint event can be raised repeatedly and at times you wouldn't expect, and may not cause a repaint of the whole form/control either. What possible reason could you have for wanting the Label to show the incrementing count of ellipses drawn every single time the Paint event is raised? That's madness!

    What is this Label actually supposed to represent? If it's the ellipses being added to the list in the first place then you only do that once and you do it before the form is displayed anyway, so what sane use is that Label? If you want the user to actually see the ellipses being added and see the Label increment accordingly then I've already shown you how that can be done. Basically, you're doing something bad for a misguided reason.
    I want the Label to update in real time as the circles are added.
    Like a running counter odometer.
    Looks dumb to draw 100 circles and then have a blank label, and then have it show 100 at the end
    I Want 1....2.3..4...5...6..7.8... animation.
    So, I force the label.refresh inside the draw loop
    Works great. Except it still seems to keep calling label.refresh after the 100 circles are drawn.

    The timer idea does not work, as explained above

  35. #35
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,299

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    Quote Originally Posted by RipVoidWinkle View Post
    So, I force the label.refresh inside the draw loop
    Works great.
    No it doesn't, but it's your app so if you think it's great then that's your prerogative.
    Quote Originally Posted by RipVoidWinkle View Post
    The timer idea does not work, as explained above
    Worked fine for me. I used the default Interval of 100. Maybe you reduced the Interval to something ridiculously small. Maybe you did something else wrong. If you're happy with what you've got, I'll spend no more time on trying to make it better.

  36. #36
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,464

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    The ellipses are being repeatedly redrawn, you just don't see it. But, you do see your label changing, so you've got to put some conditional logic there if you're keeping that functionality

  37. #37

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2014
    Posts
    313

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    Quote Originally Posted by .paul. View Post
    The ellipses are being repeatedly redrawn, you just don't see it. But, you do see your label changing, so you've got to put some conditional logic there if you're keeping that functionality
    Yep, simple IF statement inside the Paint() ForEach loop stopped the Label update after all circles are drawn.

  38. #38

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2014
    Posts
    313

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    Quote Originally Posted by jmcilhinney View Post
    No it doesn't, but it's your app so if you think it's great then that's your prerogative.

    Worked fine for me. I used the default Interval of 100. Maybe you reduced the Interval to something ridiculously small. Maybe you did something else wrong. If you're happy with what you've got, I'll spend no more time on trying to make it better.
    Yea, I used a faster interval, and more circles.
    That's when the timer method fails, since it ticks() before circles are done drawing.
    So, then the screen looks frozen since it can only draw the same first n circles for each tick, no new ones.

  39. #39
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,299

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    Quote Originally Posted by RipVoidWinkle View Post
    it ticks() before circles are done drawing.
    Drawing or painting? As I have said, they are two different things. Your code does the drawing and that is fast, then the system does the painting and that is slow. You reduce the amount of painting that gets done, thus improving performance, by invalidating the smallest area possible and thus painting the smallest area possible. Did you do that? Also, how small was the Interval and how small do you realistically think it should be such that an incrementing number in a Label is actually of any practical value? If that number is just a blur that the user can't even make out a specific number from then what's the point?

  40. #40

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2014
    Posts
    313

    Re: Need help with DrawEllipse() and Me.Refresh() and Label1.text

    I have a thread.sleep in the paint() for each loop
    rendering is deliberately slowed so user can see circles appearing while counter rolls over

Page 1 of 2 12 LastLast

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