none
Sending graphics developed in a sub to an object RRS feed

  • Question

  • I am relatively new to working with graphic objects but with the help of people here have gotten a good feel of it. I finished my first part of a project I am working on which runs fine but after looking at my code I thought I might be able to minimize a lot of redundancy if I could build subs or functions that would allow me to build the graphics within the sub and then send the graphics out of the sub to an object which in my case is a picture box on a form.  Through my reading in this forum it seems that its preferred to do graphics inside of a panel but I don't understand what the difference is.  As an example if I can build lets say text that I can pass to a sub and then do what I have to do with it and then send it out to an object I think that would cut down a lot of my coding. So lets say I have an equation like f(x) = x^2 -3x+5 I would like to be able to send that string to a sub then turn it into a graphic and then send it outside of the sub to my picturebox on my form. If I can understand initially how to get started I think I can figure the rest out.

    Thanks in advance,

    Les

    Friday, November 22, 2019 6:27 AM

Answers

  • Yeah. Hmmm. Well I am not promising I will be any help. Especially if you already have it working how you like.

    If you have this same thing 17 equations worth then it might help to use subroutines inside the select case as shown in the example. Call subs with g graphics. However you need to pass all the variables to the sub. Correct? So a simple class structure can help. See the example. Of course this is just a start about classes you can do much more. Its not that hard to do simple things like put the sub routines in the class. It helps organize.

    Now you can define the initial values in the class once and pass that to many sub routines that use the same values. You can also just change a few of the default initial values for each etc.

    See how I divided the select case up and made two subs that the g graphics is passed to. Also these two subs use the same initial variables passed in a class to the subs. This type of class structure is easy to do.

    Does any of that look promising? It should make it easier to sort out all the different values?

    Public Class Form6
        Private Class EQ17Values
            'these values are the same for all define them here
            Public startX As Single = 4
            Public startY As Single = 6
    
            'these are the other declares for all
            Public funcX, funcY, funcW, funcH As Single
            Public limX, limY, limW, limH As Single
            Public numX, numY, numW, numH As Single
            Public denX, denY, denW, denH As Single
            Public deltaX, deltaY, deltaW, deltaH As Single
            Public divX, divY, divW As Single
            Public maxX, maxY As Single
            Public quesX, quesY As Single
            Public DivideLineLength As Single = 0
            Public SpaceBetweenLines As Integer = 20
            Public t As String
    
        End Class
    
    
        Sub EQ17i(a As Integer, b As Integer, c As Integer, d As Integer)
    
            Dim EQ17Values1 As New EQ17Values
    
    
            Using g As Graphics = Graphics.FromImage(backbuffer),
                fmt As StringFormat = CType(StringFormat.GenericTypographic.Clone, StringFormat)
    
                fmt.FormatFlags = fmt.FormatFlags Or StringFormatFlags.MeasureTrailingSpaces
                Dim stringsize As SizeF
                g.Clear(Color.White) 'paint the buffer white
    
                'determine all the geometries for the first line of the equation
                Dim DrawEquationLine As Integer
                If TotalEquationSteps = MaxEquationSteps Then
                    TotalEquationSteps = MaxEquationSteps
                Else
                    TotalEquationSteps = TotalEquationSteps + 1
                End If
    
                With EQ17Values1
                    'these vals are the same for these equtions
                    .DivideLineLength = 4
    
                    For DrawEquationLine = 1 To TotalEquationSteps
                        Select Case DrawEquationLine
                            Case = 4
                                'change only these values for this variation
                                .maxX = 100
                                .maxY = 200
                                .SpaceBetweenLines = 12
                                'call the sub with the graphics and variable values in the class
                                Eq17Part4(g, EQ17Values1)
                            Case = 5
                                .maxX = 300
                                .maxY = 500
                                .SpaceBetweenLines = 14
                                Eq17Part5(g, EQ17Values1)
                        End Select
                    Next
                End With
    
            End Using
    
        End Sub
    
        Private Sub Eq17Part4(g As Graphics, values As EQ17Values)
            'now all the values already defined in the calling sub will pass the values to this sub
    
            With values
                'so maxy was defined already 
                .startY = .maxY + .SpaceBetweenLines
    
                .numX = 0 : .denX = 0 : .numW = 0 : .denW = 0
    
                'add the remaining things part 4
                'this draws part4 on g which is the bitmap
                'you still need to make sure the bitmap is being persisted in the control same as you are now
                g.DrawRectangle(Pens.Red, .startX, .startY, .maxX - .startX, .maxY - .startY)
            End With
        End Sub
    
        Private Sub Eq17Part5(g As Graphics, values As EQ17Values)
            'now all the values already defined in the calling sub will pass the values to this sub
    
            With values
                'so maxy was defined already 
                .startY = .maxY + .SpaceBetweenLines
    
                .numX = 0 : .denX = 0 : .numW = 0 : .denW = 0
    
                'add the remaining things for part 5
    
            End With
        End Sub
    
    
    End Class

    Saturday, November 23, 2019 12:58 AM

All replies

  • Hi Les,

    You need to show a simple sample of how you make your graphics now. Then we can suggest how to improve it.

    From what you descibe I would say you want to draw in the paint event of the object you draw on whether panel, form, button, picturebox etc any control. Then you draw on the e.graphics drawing surface supplied in the e graphics arguments passed to the paint event by the system.

    And now the improvement is you make subroutines and pass the e.graphics to the subroutines from the paint event and draw on it in the subroutine. Then return to the paint event, draw some more, pass to another subroutine and etc.

    That is the most efficient way to draw.

    However one could make a bitmap and pass that to the subroutines and then in each subroutine your draw on the bitmap by creating a graphics object from the bitmap. This is less efficient but at times can work if you have lots of drawing to do and only want to update a small area of the bitmap each time you draw rather than redrawing the entire scene on the bitmap or graphics object each time.

    Did you not have some reason you used a bitmap and I always questioned it? Some reason you thought you needed to use a bitmap to measure the text size somehow??? I always thought there was a better way?? Show that if you can too.

    And finally most computers are fairly fast these days and you need to have a lot of drawing to begin to slow things enough to be noticiable and require speed improvements. Now improving the code is always good just for programming.

    So if you can me a very simple one form example of how you draw now, not giving away secrets just outlining what you do now, then we can try to make better suggestions if any.

    Also descibe best you can how and what you already have in mind for improvements. Also show a picture of the result you want etc. Show us what code you have you want to put in a subroutine etc.

    I know it sounds like a lot of work but its the best way to optimize your code now. Make a very simple example and time it. In making the example you learn it better. Then add improvements and check the time and see if it is any faster. As far as improving use of the code same thing you will get a feel for it as you make the simple example and then you will incorporate the example into your large project once you feel you understand it and have something worth while to do.

    PS do you know how to use Classes? That will be the next improvement.

    Friday, November 22, 2019 11:13 AM
  • Hi

    Here is some code that may help. The idea I used here is to pre-prepare the strings with some attributes and those added to a Dictionary along with desired colour. There are 2 Dictionaries to differentiate between strings to be drawn filled or outlined. (either can be removed if unnecessary)

    Again, here the idea is to separate the creation of the strings and the actual drawing in the Paint event - in general, this is a good idea as it keeps a lot of redundant processing out of the Paint event.

    Anyway, try this out and see if it is of use.

    Option Strict On
    Option Explicit On

    Imports System.Drawing.Drawing2D Public Class Form1 Dim GPSoutline As New Dictionary(Of GraphicsPath, Pen) Dim GPSsolid As New Dictionary(Of GraphicsPath, SolidBrush) Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load ' add strings to be OUTLINED GPSoutline.Add(MakeGP(New Point(20, 40), "Text To Make", New Font("Impact", 33), FontStyle.Regular), New Pen(Color.Blue)) GPSoutline.Add(MakeGP(New Point(60, 100), "Second Text To Make", New Font("Times New Roman", 50), FontStyle.Regular), New Pen(Color.Red)) ' add strings to be SOLID GPSsolid.Add(MakeGP(New Point(60, 80), "Third Text To Make", New Font("Arial", 25), FontStyle.Bold), New SolidBrush(Color.DarkGreen)) GPSsolid.Add(MakeGP(New Point(20, 160), "Fourth Text To Make", New Font("Arial", 40), FontStyle.Regular), New SolidBrush(Color.Maroon)) End Sub Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint ' OUTLINED TEXT For Each kvp As KeyValuePair(Of GraphicsPath, Pen) In GPSoutline e.Graphics.DrawPath(kvp.Value, kvp.Key) Next ' SOLID TEXT For Each kvp As KeyValuePair(Of GraphicsPath, SolidBrush) In GPSsolid e.Graphics.FillPath(kvp.Value, kvp.Key) Next End Sub Function MakeGP(loc As Point, s As String, f As Font, sty As FontStyle) As GraphicsPath Dim GP As New GraphicsPath(FillMode.Alternate) GP.AddString(s, f.FontFamily, sty, f.SizeInPoints, loc, StringFormat.GenericDefault) Return GP End Function End Class



    Regards Les, Livingston, Scotland


    • Edited by leshay Friday, November 22, 2019 3:27 PM
    Friday, November 22, 2019 3:13 PM
  • PS Look at the version 3 example I posted in this thread.

    https://social.msdn.microsoft.com/Forums/en-US/8f8f70ec-9a87-43c2-9ae8-957dc9c97927/how-to-draw-by-mouse-a-polygon-of-any-shape-snap-to-grid-or-not-snap-to-grid-the-snap-maybe-off?forum=vbgeneral

    See the SHAPE class? See how in the picturebox1 paint event the shape class is used and the shape.draw sub routine in the shape class is called with the e.grphics oject and another variable:

        shp.Draw(e.Graphics, Yoffset)


    So you can make a class and call it with the graphics object for the control you are drawing upon, and also any other variables you want to pass into the sub routine. You could have a text draw sub routine and pass in your string and anything else you want. Also the way this class works there is a list of shapes and these are lines and the class has data stored as variables as the points 1 and 2 of the line end points. For text you would have a string saved in the shape class and then a sub to drawText... etc.

    Does that look like something interesting?

    PS also see the DrawGrid sub routine and how it has the e.graphics passed into the sub?

    See how the paint event code calls the sub routines...

    Friday, November 22, 2019 3:25 PM
  • Hi Tom

    First let me thank you for your willingness to help.  I always see you here in the forum and you seem quite adept at dealing with graphics and I just want you to know that my app is working fine in its initial stages so lets try to keep in mind I am not as accomplished as you are in this subject <S>.  I will display one of the lines of graphics I am doing and try to supply you with some code I use to accomplish this.  The following code will probably not run with a cut and paste but you will see how I break down the various parts of the equation.  I hope this gives you enough to make some suggestions.  I know there was some mention of setting up a class but at the moment I am going to take a pass on classes.  I am just seeing if there is a more simpler way of coding but understand its not vital since I am happy with what I have up to  now and only trying to learn on suggestions you may offer me.

    Thanks Tom,

    Les

        Sub EQ17i(a As Integer, b As Integer, c As Integer, d As Integer)
            Dim startX, startY As Single
            Dim funcX, funcY, funcW, funcH As Single
            Dim limX, limY, limW, limH As Single
            Dim numX, numY, numW, numH As Single
            Dim denX, denY, denW, denH As Single
            Dim deltaX, deltaY, deltaW, deltaH As Single
            Dim divX, divY, divW As Single
            Dim maxX, maxY As Single
            Dim quesX, quesY As Single
            Dim DivideLineLength As Single = 0
            Dim SpaceBetweenLines = 20
            Dim t As String
            Using g As Graphics = Graphics.FromImage(backbuffer),
                fmt As StringFormat = CType(StringFormat.GenericTypographic.Clone, StringFormat)
                fmt.FormatFlags = fmt.FormatFlags Or StringFormatFlags.MeasureTrailingSpaces
                Dim stringsize As SizeF
                g.Clear(Color.White) 'paint the buffer white
                'determine all the geometries for the first line of the equation
                Dim DrawEquationLine As Integer
                If TotalEquationSteps = MaxEquationSteps Then
                    TotalEquationSteps = MaxEquationSteps
                Else
                    TotalEquationSteps = TotalEquationSteps + 1
                End If
                For DrawEquationLine = 1 To TotalEquationSteps
                    Select Case DrawEquationLine
                        Case = 4
                            startY = maxY + SpaceBetweenLines
                            numX = 0 : denX = 0 : numW = 0 : denW = 0
    
                            'Numerator calculations
                            t = Tfunc(1, "b", b) & "[" & "x"
                            stringsize = g.MeasureString(t, f1, 0, fmt)
                            numW = numW + stringsize.Width
    
                            t = "2"
                            stringsize = g.MeasureString(t, f2, 0, fmt)
                            numW = numW + stringsize.Width
    
                            t = "+2xdx+(dx)"
                            stringsize = g.MeasureString(t, f1, 0, fmt)
                            numW = numW + stringsize.Width
    
                            t = "2"
                            stringsize = g.MeasureString(t, f2, 0, fmt)
                            numW = numW + stringsize.Width
    
                            t = "]" & Tfunc(2, "c", c) & "(x+dx)"
                            stringsize = g.MeasureString(t, f1, 0, fmt)
                            numW = numW + stringsize.Width
    
                            t = Tfunc(3, "d", d) & "-("
                            stringsize = g.MeasureString(t, f1, 0, fmt)
                            numW = numW + stringsize.Width : numH = stringsize.Height
    
                            t = Tfunc(1, "b", b) & "x"
                            stringsize = g.MeasureString(t, f1, 0, fmt)
                            numW = numW + stringsize.Width
    
                            t = "2"
                            stringsize = g.MeasureString(t, f2, 0, fmt)
                            numW = numW + stringsize.Width
    
                            t = Tfunc(2, "c", c) & "x"
                            stringsize = g.MeasureString(t, f1, 0, fmt)
                            numW = numW + stringsize.Width
    
                            t = Tfunc(3, "d", d) & ")"
                            stringsize = g.MeasureString(t, f1, 0, fmt)
                            numW = numW + stringsize.Width
    
                            'Denominator calculations
                            t = "dx"
                            stringsize = g.MeasureString(t, f1, 0, fmt)
                            denW = denW + stringsize.Width : denH = stringsize.Height
    
                            'Determine which is longer the numerator or denominator
                            If denW >= numW Then
                                DivideLineLength = denW
                            Else
                                DivideLineLength = numW
                            End If
    
                            'f'(x) calculations
                            t = "f'(x) = "
                            stringsize = g.MeasureString(t, f1, 0, fmt)
                            funcX = startX : funcY = startY + numH / 2 : funcW = stringsize.Width : funcH = stringsize.Height
    
                            'limit calculations
                            t = "limit  "
                            stringsize = g.MeasureString(t, f1, 0, fmt)
                            limX = funcX + funcW : limY = funcY : limW = stringsize.Width : limH = stringsize.Height
    
                            'delta x calculations
                            t = "dx" & ChrW(&H27F6) & "0"
                            stringsize = g.MeasureString(t, f3, 0, fmt)
                            deltaX = limX : deltaY = limY + limH : deltaW = stringsize.Width : deltaH = stringsize.Height
    
                            divX = limX + limW : divY = limY + limH / 2 : divW = DivideLineLength
                            denX = limX + limW + (divW - denW) / 2
                            denY = divY
    
                            Dim blackPen As New Pen(Color.Black, 2)
                            g.DrawLine(blackPen, divX, divY, divX + divW, divY)
    
                            'draws the f'(x)
                            t = "f'(x) = "
                            g.DrawString(t, f1, New SolidBrush(Color.Black), New Point(CInt(funcX), CInt(funcY)), fmt)
                            maxX = GetMaxX(funcX + funcW, maxX)
                            maxY = GetMaxY(funcH, maxY)
    
                            'draws the limit
                            t = "limit  "
                            g.DrawString(t, f1, New SolidBrush(Color.Black), New Point(CInt(limX), CInt(limY)), fmt)
                            maxX = GetMaxX(limX + limW, maxX)
                            maxY = GetMaxY(limH, maxY)
    
                            'draws the delta x
                            t = "dx" & ChrW(&H27F6) & "0"
                            g.DrawString(t, f3, New SolidBrush(Color.Black), New Point(CInt(deltaX), CInt(deltaY)), fmt)
                            maxX = GetMaxX(deltaX + deltaW, maxX)
                            maxY = GetMaxY(deltaH, maxY)
    
                            'draws the numerator
                            numX = limX + limW
                            numY = startY
    
                            t = Tfunc(1, "b", b) & "[" & "x"
                            stringsize = g.MeasureString(t, f1, New Point(CInt(numX), CInt(numY)), fmt)
                            'maxY = GetMaxY(stringsize.Height, maxY)
                            numX = limX + limW + (divW - numW) / 2
                            numY = divY - numH
                            g.DrawString(t, f1, New SolidBrush(Color.Black), New Point(CInt(numX), CInt(numY)), fmt)
                            numX = numX + stringsize.Width
                            maxX = GetMaxX(numX, maxX)
                            maxY = GetMaxY(stringsize.Height, maxY)
    
                            t = "2"
                            stringsize = g.MeasureString(t, f2, New Point(CInt(numX), CInt(numY)), fmt)
                            g.DrawString(t, f2, New SolidBrush(Color.Black), New Point(CInt(numX), CInt(numY)), fmt)
                            numX = numX + stringsize.Width
                            maxX = GetMaxX(numX, maxX)
                            maxY = GetMaxY(stringsize.Height, maxY)
    
    
                            t = "+2xdx+(dx)"
                            stringsize = g.MeasureString(t, f1, New Point(CInt(numX), CInt(numY)), fmt)
                            g.DrawString(t, f1, New SolidBrush(Color.Black), New Point(CInt(numX), CInt(numY)), fmt)
                            numX = numX + stringsize.Width
                            maxX = GetMaxX(numX, maxX)
                            maxY = GetMaxY(stringsize.Height, maxY)
    
                            t = "2"
                            stringsize = g.MeasureString(t, f2, New Point(CInt(numX), CInt(numY)), fmt)
                            g.DrawString(t, f2, New SolidBrush(Color.Black), New Point(CInt(numX), CInt(numY)), fmt)
                            numX = numX + stringsize.Width
                            maxX = GetMaxX(numX, maxX)
                            maxY = GetMaxY(stringsize.Height, maxY)
    
                            t = "]" & Tfunc(2, "c", c) & "(x+dx)"
                            stringsize = g.MeasureString(t, f1, New Point(CInt(numX), CInt(numY)), fmt)
                            g.DrawString(t, f1, New SolidBrush(Color.Black), New Point(CInt(numX), CInt(numY)), fmt)
                            numX = numX + stringsize.Width
                            maxX = GetMaxX(numX, maxX)
                            maxY = GetMaxY(stringsize.Height, maxY)
    
                            t = Tfunc(3, "d", d) & "-("
                            stringsize = g.MeasureString(t, f1, New Point(CInt(numX), CInt(numY)), fmt)
                            g.DrawString(t, f1, New SolidBrush(Color.Black), New Point(CInt(numX), CInt(numY)), fmt)
                            numX = numX + stringsize.Width
                            maxX = GetMaxX(numX, maxX)
                            maxY = GetMaxY(stringsize.Height, maxY)
    
                            t = Tfunc(1, "b", b) & "x"
                            stringsize = g.MeasureString(t, f1, New Point(CInt(numX), CInt(numY)), fmt)
                            g.DrawString(t, f1, New SolidBrush(Color.Black), New Point(CInt(numX), CInt(numY)), fmt)
                            numX = numX + stringsize.Width
                            maxX = GetMaxX(numX, maxX)
                            maxY = GetMaxY(stringsize.Height, maxY)
    
                            t = "2"
                            stringsize = g.MeasureString(t, f2, New Point(CInt(numX), CInt(numY)), fmt)
                            g.DrawString(t, f2, New SolidBrush(Color.Black), New Point(CInt(numX), CInt(numY)), fmt)
                            numX = numX + stringsize.Width
                            maxX = GetMaxX(numX, maxX)
                            maxY = GetMaxY(stringsize.Height, maxY)
    
                            t = Tfunc(2, "c", c) & "x"
                            stringsize = g.MeasureString(t, f1, New Point(CInt(numX), CInt(numY)), fmt)
                            g.DrawString(t, f1, New SolidBrush(Color.Black), New Point(CInt(numX), CInt(numY)), fmt)
                            numX = numX + stringsize.Width
                            maxX = GetMaxX(numX, maxX)
                            maxY = GetMaxY(stringsize.Height, maxY)
    
                            t = Tfunc(3, "d", d) & ")"
                            stringsize = g.MeasureString(t, f1, New Point(CInt(numX), CInt(numY)), fmt)
                            g.DrawString(t, f1, New SolidBrush(Color.Black), New Point(CInt(numX), CInt(numY)), fmt)
                            numX = numX + stringsize.Width
                            maxX = GetMaxX(numX, maxX)
                            maxY = GetMaxY(stringsize.Height, maxY)
    
                            'draws the denominator
                            t = "dx"
                            stringsize = g.MeasureString(t, f1, New Point(CInt(denX), CInt(denY)), fmt)
                            g.DrawString(t, f1, New SolidBrush(Color.Black), New Point(CInt(denX), CInt(denY)), fmt)
                            maxX = GetMaxX(denX + denW, maxX)
                            maxY = GetMaxY(denY + stringsize.Height, maxY)
                            g.DrawRectangle(Pens.Red, startX, startY, maxX - startX, maxY - startY)
    

    Friday, November 22, 2019 11:23 PM
  • Yeah. Hmmm. Well I am not promising I will be any help. Especially if you already have it working how you like.

    If you have this same thing 17 equations worth then it might help to use subroutines inside the select case as shown in the example. Call subs with g graphics. However you need to pass all the variables to the sub. Correct? So a simple class structure can help. See the example. Of course this is just a start about classes you can do much more. Its not that hard to do simple things like put the sub routines in the class. It helps organize.

    Now you can define the initial values in the class once and pass that to many sub routines that use the same values. You can also just change a few of the default initial values for each etc.

    See how I divided the select case up and made two subs that the g graphics is passed to. Also these two subs use the same initial variables passed in a class to the subs. This type of class structure is easy to do.

    Does any of that look promising? It should make it easier to sort out all the different values?

    Public Class Form6
        Private Class EQ17Values
            'these values are the same for all define them here
            Public startX As Single = 4
            Public startY As Single = 6
    
            'these are the other declares for all
            Public funcX, funcY, funcW, funcH As Single
            Public limX, limY, limW, limH As Single
            Public numX, numY, numW, numH As Single
            Public denX, denY, denW, denH As Single
            Public deltaX, deltaY, deltaW, deltaH As Single
            Public divX, divY, divW As Single
            Public maxX, maxY As Single
            Public quesX, quesY As Single
            Public DivideLineLength As Single = 0
            Public SpaceBetweenLines As Integer = 20
            Public t As String
    
        End Class
    
    
        Sub EQ17i(a As Integer, b As Integer, c As Integer, d As Integer)
    
            Dim EQ17Values1 As New EQ17Values
    
    
            Using g As Graphics = Graphics.FromImage(backbuffer),
                fmt As StringFormat = CType(StringFormat.GenericTypographic.Clone, StringFormat)
    
                fmt.FormatFlags = fmt.FormatFlags Or StringFormatFlags.MeasureTrailingSpaces
                Dim stringsize As SizeF
                g.Clear(Color.White) 'paint the buffer white
    
                'determine all the geometries for the first line of the equation
                Dim DrawEquationLine As Integer
                If TotalEquationSteps = MaxEquationSteps Then
                    TotalEquationSteps = MaxEquationSteps
                Else
                    TotalEquationSteps = TotalEquationSteps + 1
                End If
    
                With EQ17Values1
                    'these vals are the same for these equtions
                    .DivideLineLength = 4
    
                    For DrawEquationLine = 1 To TotalEquationSteps
                        Select Case DrawEquationLine
                            Case = 4
                                'change only these values for this variation
                                .maxX = 100
                                .maxY = 200
                                .SpaceBetweenLines = 12
                                'call the sub with the graphics and variable values in the class
                                Eq17Part4(g, EQ17Values1)
                            Case = 5
                                .maxX = 300
                                .maxY = 500
                                .SpaceBetweenLines = 14
                                Eq17Part5(g, EQ17Values1)
                        End Select
                    Next
                End With
    
            End Using
    
        End Sub
    
        Private Sub Eq17Part4(g As Graphics, values As EQ17Values)
            'now all the values already defined in the calling sub will pass the values to this sub
    
            With values
                'so maxy was defined already 
                .startY = .maxY + .SpaceBetweenLines
    
                .numX = 0 : .denX = 0 : .numW = 0 : .denW = 0
    
                'add the remaining things part 4
                'this draws part4 on g which is the bitmap
                'you still need to make sure the bitmap is being persisted in the control same as you are now
                g.DrawRectangle(Pens.Red, .startX, .startY, .maxX - .startX, .maxY - .startY)
            End With
        End Sub
    
        Private Sub Eq17Part5(g As Graphics, values As EQ17Values)
            'now all the values already defined in the calling sub will pass the values to this sub
    
            With values
                'so maxy was defined already 
                .startY = .maxY + .SpaceBetweenLines
    
                .numX = 0 : .denX = 0 : .numW = 0 : .denW = 0
    
                'add the remaining things for part 5
    
            End With
        End Sub
    
    
    End Class

    Saturday, November 23, 2019 12:58 AM
  • Hi Tom,

    Ok I see your 2 posts and I thank you very much for them.  I will study later tonight and see what is going on.  BTW why do you prefer to use the paint instead of sending the graphics to a buffer, just want to understand the difference.  Also why do most people in this forum prefer sending graphics to a panel instead of a picturebox?? Does it really matter? I know with a picturebox I have to keep track of the width and height of my buffer and perhaps the panel does it automatically??

    Once again thx Tom

    Les

    Saturday, November 23, 2019 1:35 AM
  • Hi Tom,

    Ok I see your 2 posts and I thank you very much for them.  I will study later tonight and see what is going on.  BTW why do you prefer to use the paint instead of sending the graphics to a buffer, just want to understand the difference.  Also why do most people in this forum prefer sending graphics to a panel instead of a picturebox?? Does it really matter? I know with a picturebox I have to keep track of the width and height of my buffer and perhaps the panel does it automatically??

    Once again thx Tom

    Les

    " BTW why do you prefer to use the paint instead of sending the graphics to a buffer, just want to understand the difference"

    Because you dont need the bitmap "buffer" so its a waste of time. The picturebox is the buffer when you draw on e.graphics. Why make a memory bitmap graphics buffer and then copy that to the picturebox? Cut out the bitmap middle man. Draw on the picturebox.

    Now there are times when it is more conveient or requires a bitmap to draw on but for most things you can just draw directly on the control you dont need a bitmap. So all that code you have using a bitmap can be eliminated.


    "why do most people in this forum prefer sending graphics to a panel instead of a picturebox?"

    Because they dont understand the difference. Actually a panel uses less resources but has things missing like doublebuffer etc. Again for most things these days there is not much difference. But if you are drawing much you should use a picturebox IMHO. Panels are containers.

    "I know with a picturebox I have to keep track of the width and height of my buffer and perhaps the panel does it automatically"

    No. They are the same in this regard. You can switch them back and forth and use the same code. But the panel will blink and flicker each time you update because it lacks doublebuffer while the picturebox will not. Also picturebox has image and background image panel has only background. Other gotchas with panels. Of course you can make your own panel class and add double buffer...


    Saturday, November 23, 2019 2:08 AM
  • Hi Tom,

    Very clear explanation to my questions!  I thank you for that. Later tonight I will delve into your suggestions and study them.

    Thanks,

    Les

    Saturday, November 23, 2019 4:09 AM
  • Hi,

    Did you resolve the issue? If you have resolved the issue then pleasse mark the post or posts that helped you as The Answer using the Mark as Answer link at the bottom of the post. Marking answers will help other community members find solutions in the future.

    Best Regards,

    Julie


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    Tuesday, November 26, 2019 3:17 AM
    Moderator
  • Hi Julie I am not done trying to understand the above post from Tom. As you can see when I am at a point I always try to remember to acknowledge anyone or persons who have helped me.

    Thx

    Les

    Friday, November 29, 2019 7:22 AM
  • Hi Tom,

    Thank you so much for your valued thoughts.  This gives me some ideas to work with.  As always I thank you for your direction and thoughts.

    Les

    3 hours 26 minutes ago
  • Hi Les,

    Appreciate you taking the time to educate me.  From some books I have been reading it seems that going through the dictionary is probably not preferred but what do I know here <S>.  Anyway I have learned about the dictionary with your help and I thank you very much.

    ps Sorry it took so long to reply but I had a water heater burst at the house and obviously that took priority.

    Thanks,

    Les

    3 hours 22 minutes ago