none
Draw a line after command button is clicked RRS feed

  • Question

  • Hi:

    I am using vb.net 2019, and I would like to draw a line, which is fairly simple.  As you can see from my sample code, the drawing is done in the paint event.  However, this will always draw the line no matter what.  What I would like to do is for the user to input the starting coordinates of the line in two textboxes (x,y), and then click a command button.  Only after the user clicks the command button, the line to be drawn in the picturebox and to stay in the picturebox. 

    I would appreciate a sample code.  thank you.

    Bob

    Private Sub PictureBox3_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox3.Paint
            Dim XS As Single, YS As Single
            Dim pen As New Pen(Color.FromArgb(255, 0, 0, 255), 8)
            pen.StartCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor
            pen.EndCap = System.Drawing.Drawing2D.LineCap.RoundAnchor
            XS = textbox1.text
            YS = textbox2.text
            e.Graphics.DrawLine(pen, XS, YS, 300, 175)
        End Sub

    Friday, July 5, 2019 7:11 PM

Answers

  • Thanks Viorel.  This is great, except, when I change the setting of the two textboxes to draw another line, it erases the content of the picturebox. Is there a way to keep the content.  Thanks.

    Bob


    There are two ways to make your drawing persist on the screen. One way is save the coordinates of multiple objects and then do all the drawing in the picturebox paint event everytime the paint event is called. Another way to persist the image is to draw each update on a memory bitmap and then show the latest bitmap in the picturebox.

    That is a fundemental thing about graphics you need to learn. Look up persist image etc.

    There are good and bad things with each method depending on what you want to acheive.

    For example you cant recreate a freehand bitmap drawing but you can a paintevent "vector" drawing that you save the object data for.

    So you need to decide which method now. How do you want to save the drawing? Do you want to edit the drawing after saving? As you get more complex you will want the paint vector drawing method like a CAD program uses. The bitmap method is like windows Paint application uses. Things like photographs are edited in the bitmap paint program. Drawings of houses are made in CAD programs and include dimensions.

    This example uses the draw on memory bitmap method. Viorel's is the draw in paint event method for one object.

    The example makes the controls. To run just cut and paste into an empty form. Change the form name as reqd. Change the file paths to your images.

    Public Class Form5
        Private WithEvents Pic1 As New PictureBox With {.Parent = Me,
           .Location = New Point(10, 10), .Size = New Size(120, 120),
           .BackgroundImage = Image.FromFile("c:\bitmaps\a1a.png"),
           .BackgroundImageLayout = ImageLayout.Zoom, .BackColor = Color.White}
        Private WithEvents Pic2 As New PictureBox With {.Parent = Me,
            .Location = New Point(150, 10), .Size = New Size(120, 120),
            .BackgroundImage = Image.FromFile("c:\bitmaps\a1b.png"),
            .BackgroundImageLayout = ImageLayout.Zoom, .BackColor = Color.White}
        Private WithEvents Pic3 As New PictureBox With {.Parent = Me,
            .Location = New Point(150, 150), .Size = New Size(120, 120),
            .BackgroundImageLayout = ImageLayout.Zoom, .BackColor = Color.White}
        Private WithEvents AddLineBtn As New Button With {.Parent = Me,
            .Location = New Point(40, 220), .Size = New Size(80, 24), .Text = "Add Line"}
        Private WithEvents ClearBtn As New Button With {.Parent = Me,
            .Location = New Point(40, 260), .Size = New Size(80, 24), .Text = "Clear"}
    
        Private WithEvents TextY As New TextBox With {.Parent = Me,
            .Location = New Point(40, 180), .Size = New Size(60, 32)}
    
        Private Sub Form3_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            ClientSize = New Size(300, 300)
            Combine()
        End Sub
    
        Private Sub Combine()
            'make one combined image from two selected images in pic boxes 1 and 2
            Dim bmp1 As Bitmap = CType(Pic1.BackgroundImage, Bitmap)
            Dim bmp2 As Bitmap = CType(Pic2.BackgroundImage, Bitmap)
            Dim bmp3 As New Bitmap(bmp1.Width, bmp1.Height)
    
            Using g As Graphics = Graphics.FromImage(bmp3)
    
                g.DrawImage(bmp1, New Rectangle(0, 0, bmp1.Width, bmp1.Height))
    
                'draw second image on bmp with white transparent color range
                Dim attr1 As New System.Drawing.Imaging.ImageAttributes
                attr1.SetColorKey(Color.FromArgb(250, 250, 250), Color.FromArgb(255, 255, 255))
                g.DrawImage(bmp2, New Rectangle(0, 0, bmp2.Width, bmp2.Height),
                            0, 0, bmp2.Width, bmp2.Height, GraphicsUnit.Pixel, attr1)
    
                'show the combined image in pic3
                If Pic3.BackgroundImage IsNot Nothing Then Pic3.BackgroundImage.Dispose()
                Pic3.BackgroundImage = bmp3
            End Using
        End Sub
    
        Private Sub AddLineBtn_Click(sender As Object, e As EventArgs) Handles AddLineBtn.Click
            'add the line to the picturebox3 image
            If Pic3.BackgroundImage Is Nothing Then Combine()
    
            Dim bmp As New Bitmap(Pic3.BackgroundImage.Width, Pic3.BackgroundImage.Height)
    
            'this should be done with tryparse etc
            Dim y1 As Single = CSng(TextY.Text)
    
            Using g As Graphics = Graphics.FromImage(bmp),
                    p As New Pen(Color.Red, 8)
                g.DrawImage(Pic3.BackgroundImage, 0, 0)
    
                g.DrawLine(p, 0, y1, 900, y1)
    
                Pic3.BackgroundImage.Dispose()
                Pic3.BackgroundImage = bmp
            End Using
        End Sub
    
        Private Sub ClearBtn_Click(sender As Object, e As EventArgs) Handles ClearBtn.Click
            'remake the combined image
            Combine()
        End Sub
    End Class

    • Marked as answer by booboo_US Sunday, July 7, 2019 3:03 AM
    Saturday, July 6, 2019 10:54 AM

All replies

  • Try these event handlers:

    Dim Draw As Boolean = False
    Dim XS As Single
    Dim YS As Single
    
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    
       Draw = Single.TryParse(TextBox1.Text, XS) AndAlso Single.TryParse(TextBox2.Text, YS)
       PictureBox3.Invalidate()
    
    End Sub
    
    Private Sub PictureBox3_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox3.Paint
    
       If Draw Then
    
          Using pen As New Pen(Color.Blue, 8) With {.StartCap = LineCap.ArrowAnchor, .EndCap = LineCap.RoundAnchor}
             e.Graphics.DrawLine(pen, XS, YS, 300, 175)
          End Using
    
       End If
    
    End Sub



    • Edited by Viorel_MVP Friday, July 5, 2019 7:41 PM
    • Proposed as answer by tommytwotrain Saturday, July 6, 2019 10:55 AM
    Friday, July 5, 2019 7:36 PM
  • Thanks Viorel.  This is great, except, when I change the setting of the two textboxes to draw another line, it erases the content of the picturebox. Is there a way to keep the content.  Thanks.

    Bob

    Friday, July 5, 2019 8:09 PM
  • Thanks Viorel.  This is great, except, when I change the setting of the two textboxes to draw another line, it erases the content of the picturebox. Is there a way to keep the content.  Thanks.

    Bob


    There are two ways to make your drawing persist on the screen. One way is save the coordinates of multiple objects and then do all the drawing in the picturebox paint event everytime the paint event is called. Another way to persist the image is to draw each update on a memory bitmap and then show the latest bitmap in the picturebox.

    That is a fundemental thing about graphics you need to learn. Look up persist image etc.

    There are good and bad things with each method depending on what you want to acheive.

    For example you cant recreate a freehand bitmap drawing but you can a paintevent "vector" drawing that you save the object data for.

    So you need to decide which method now. How do you want to save the drawing? Do you want to edit the drawing after saving? As you get more complex you will want the paint vector drawing method like a CAD program uses. The bitmap method is like windows Paint application uses. Things like photographs are edited in the bitmap paint program. Drawings of houses are made in CAD programs and include dimensions.

    This example uses the draw on memory bitmap method. Viorel's is the draw in paint event method for one object.

    The example makes the controls. To run just cut and paste into an empty form. Change the form name as reqd. Change the file paths to your images.

    Public Class Form5
        Private WithEvents Pic1 As New PictureBox With {.Parent = Me,
           .Location = New Point(10, 10), .Size = New Size(120, 120),
           .BackgroundImage = Image.FromFile("c:\bitmaps\a1a.png"),
           .BackgroundImageLayout = ImageLayout.Zoom, .BackColor = Color.White}
        Private WithEvents Pic2 As New PictureBox With {.Parent = Me,
            .Location = New Point(150, 10), .Size = New Size(120, 120),
            .BackgroundImage = Image.FromFile("c:\bitmaps\a1b.png"),
            .BackgroundImageLayout = ImageLayout.Zoom, .BackColor = Color.White}
        Private WithEvents Pic3 As New PictureBox With {.Parent = Me,
            .Location = New Point(150, 150), .Size = New Size(120, 120),
            .BackgroundImageLayout = ImageLayout.Zoom, .BackColor = Color.White}
        Private WithEvents AddLineBtn As New Button With {.Parent = Me,
            .Location = New Point(40, 220), .Size = New Size(80, 24), .Text = "Add Line"}
        Private WithEvents ClearBtn As New Button With {.Parent = Me,
            .Location = New Point(40, 260), .Size = New Size(80, 24), .Text = "Clear"}
    
        Private WithEvents TextY As New TextBox With {.Parent = Me,
            .Location = New Point(40, 180), .Size = New Size(60, 32)}
    
        Private Sub Form3_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            ClientSize = New Size(300, 300)
            Combine()
        End Sub
    
        Private Sub Combine()
            'make one combined image from two selected images in pic boxes 1 and 2
            Dim bmp1 As Bitmap = CType(Pic1.BackgroundImage, Bitmap)
            Dim bmp2 As Bitmap = CType(Pic2.BackgroundImage, Bitmap)
            Dim bmp3 As New Bitmap(bmp1.Width, bmp1.Height)
    
            Using g As Graphics = Graphics.FromImage(bmp3)
    
                g.DrawImage(bmp1, New Rectangle(0, 0, bmp1.Width, bmp1.Height))
    
                'draw second image on bmp with white transparent color range
                Dim attr1 As New System.Drawing.Imaging.ImageAttributes
                attr1.SetColorKey(Color.FromArgb(250, 250, 250), Color.FromArgb(255, 255, 255))
                g.DrawImage(bmp2, New Rectangle(0, 0, bmp2.Width, bmp2.Height),
                            0, 0, bmp2.Width, bmp2.Height, GraphicsUnit.Pixel, attr1)
    
                'show the combined image in pic3
                If Pic3.BackgroundImage IsNot Nothing Then Pic3.BackgroundImage.Dispose()
                Pic3.BackgroundImage = bmp3
            End Using
        End Sub
    
        Private Sub AddLineBtn_Click(sender As Object, e As EventArgs) Handles AddLineBtn.Click
            'add the line to the picturebox3 image
            If Pic3.BackgroundImage Is Nothing Then Combine()
    
            Dim bmp As New Bitmap(Pic3.BackgroundImage.Width, Pic3.BackgroundImage.Height)
    
            'this should be done with tryparse etc
            Dim y1 As Single = CSng(TextY.Text)
    
            Using g As Graphics = Graphics.FromImage(bmp),
                    p As New Pen(Color.Red, 8)
                g.DrawImage(Pic3.BackgroundImage, 0, 0)
    
                g.DrawLine(p, 0, y1, 900, y1)
    
                Pic3.BackgroundImage.Dispose()
                Pic3.BackgroundImage = bmp
            End Using
        End Sub
    
        Private Sub ClearBtn_Click(sender As Object, e As EventArgs) Handles ClearBtn.Click
            'remake the combined image
            Combine()
        End Sub
    End Class

    • Marked as answer by booboo_US Sunday, July 7, 2019 3:03 AM
    Saturday, July 6, 2019 10:54 AM
  • Thank you Tommytwotrain.  As always, I appreciate your great help and explanation.

    Bob

    Sunday, July 7, 2019 3:03 AM