none
Create dyamically re-sizable line\shape winforms RRS feed

  • Question

  • I am new to programming. Can anybody help me with creating line/shape in picturebox with grips on the line/shape. Like we do it in CAD software's.

    And i want to know how to create a line on mouse click until another mouse click event occurs.

    When I draw a line using createGraphics() it creates the line continuously from selected point. Whereas I want to create a line only for showing user the path of line. And i have implemented selection rectangle an right click button

    Procedure for working: Toolbar will contain line and Area

    • Open a file(image file)
    • click on line button of toolbar
    • *Come to picturebox
    • *click on one point of screen
    • *dynamic line starts drawing on screen (line will be from the 1st clicked point to where ever mouse mouse)
    • *when user clicks the next time the line is created.

    • click area of toolbar

    • *come back to picturebox

    • *operation same like line but when user clicks third point on picture box a shaded rectangle should appear.

    Public Class Form1
    
    Dim isDrag As Boolean = False
    Dim theRectangle As New Rectangle(New Point(0, 0), New Size(0, 0))
    Dim startPoint As Point
    Dim IsDimension As Boolean = False
    Dim LineLocationStPoint As Point = Nothing
    Dim LineLocationEndPoint As Point = Nothing
    Dim cnt As Integer = 0
    Dim LineArray As New ArrayList
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim fd As OpenFileDialog = New OpenFileDialog()
        Dim strFileName As String
    
        fd.Title = "Open File Dialog"
        fd.Filter = "(*.PDF;*.DWG;*.TIFF;*.TIF)|*.PDF;*.DWG;*.TIFF;*.TIF|All files (*.*)|*.*"
        fd.FilterIndex = 2
        fd.RestoreDirectory = True
    
        If fd.ShowDialog() = DialogResult.OK Then
            strFileName = fd.FileName
            'ShowFileInWebBrowser(WebBrowser1, strFileName)
            PictureBox1.Load(strFileName)
        End If
    End Sub
    Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As  _
        System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
        If (e.Button = MouseButtons.Right) Then
            isDrag = True
        End If
    
        Dim control As Control = CType(sender, Control)
    
    
        startPoint = control.PointToScreen(New Point(e.X, e.Y))
    
        If (e.Button = MouseButtons.Left) Then
            IsDimension = True
            LineLocationStPoint = e.Location
            LineArray.Add(e.Location)
        End If
    End Sub
    
    Private  Sub Form1_MouseMove(ByVal sender As Object, ByVal e As  _
    System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
    
    
        If (isDrag) Then
    
            ControlPaint.DrawReversibleFrame(theRectangle, Me.BackColor, _
                FrameStyle.Dashed)
    
    
             Dim endPoint As Point = CType(sender, Control).PointToScreen(New Point(e.X, e.Y))
             Dim width As Integer = endPoint.X - startPoint.X
             Dim height As Integer = endPoint.Y - startPoint.Y
             theRectangle = New Rectangle(startPoint.X, startPoint.Y, _
                width, height)
    
             ControlPaint.DrawReversibleFrame(theRectangle, Me.BackColor, _
                 FrameStyle.Dashed)
        End If
        If IsDimension Then
            LineLocationEndPoint = e.Location
            Dim g As Graphics = PictureBox1.CreateGraphics()
            g.DrawLine(Pens.Red, LineLocationStPoint, e.Location)
            g.Dispose()
        End If
    End Sub
    
    Private Sub Form1_MouseUp(ByVal sender As Object, ByVal e As  _
    System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp
    
        If IsDimension Then
            PictureBox1.Refresh()
        ElseIf isDrag Then
            ' If the MouseUp event occurs, the user is not dragging.
            isDrag = False
    
            ' Draw the rectangle to be evaluated. Set a dashed frame style 
            ' using the FrameStyle enumeration.
            ControlPaint.DrawReversibleFrame(theRectangle, Me.BackColor, _
                FrameStyle.Dashed)
    
            ' Find out which controls intersect the rectangle and change their color.
            ' The method uses the RectangleToScreen method to convert the 
            ' Control's client coordinates to screen coordinates.
            Dim i As Integer
            Dim controlRectangle As Rectangle
            For i = 0 To Controls.Count - 1
                controlRectangle = Controls(i).RectangleToScreen _
                    (Controls(i).ClientRectangle)
                If controlRectangle.IntersectsWith(theRectangle) Then
                    Controls(i).BackColor = Color.BurlyWood
                End If
            Next
    
            ' Reset the rectangle.
            theRectangle = New Rectangle(0, 0, 0, 0)
        End If       
    
    End Sub


    Sunday, August 6, 2017 5:40 AM

All replies

  • Yes well that will take a year or two.

    In the mean time, you need to learn how to persist your graphics.

    The way windows works is each window is redrawn by the system each time it needs updating. The system tells us when these updates are required by calling the paint event for the control. And the system passes a drawing surface to us in the paint event in the paint event arguments. The argument e.graphics is the temporary drawing surface we are given to draw on in the paint event. So when the paint event fires, we draw all our graphics. Then, next time the window needs updating, we need to draw all our graphics again.

    This example uses the paint event to draw a line. So if the window is covered and uncovered by another application or some other reason, the paint event fires and we draw our line.

    The probem is that each time the paint event fires the window is completely erased and need to be completly redrawn.

    If we only draw our line in the mouse move event, using create graphics, we get a line, and then it is immediately erased by the system. And we dont know when to draw again unless the mouse is moving. So using create graphics in the mouse move event does not work very well. It is better to draw in the paint event, then call the paint event in the mouse move event. In this way, we get all the calls to redraw the window, not just mouse move event. Then when we want to cause the window to be redrawn, we just call the paint event by using control.refresh/invalidate.

    You can see in this example, the paint event is fired in the mousemove event by using invalidate to fire the paint event for the form control. Then in the paint event we draw our line on the e.graphics drawing surface passed to us by the system in the paint event arguments e.

    Here is a detailed example that takes years to master.

    https://msdn.microsoft.com/en-us/library/ms973830.aspx?f=255&MSPPError=-2147217396

    So you need to take it one step at a time. Just draw a line first. Then a rectangle. Then add a toolbar and on and on...

    Public Class Form2
        Private MouseDownPt, MouseMovePt As PointF
        Private PenColor As Color = Color.Yellow
    
        Private Sub Form3_Load(sender As Object, e As EventArgs) Handles Me.Load
            DoubleBuffered = True
        End Sub
    
        Private Sub Form3_MouseDown(sender As Object, e As MouseEventArgs) Handles Me.MouseDown
            MouseDownPt = e.Location
            MouseMovePt = e.Location
        End Sub
    
        Private Sub Form3_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove
            If e.Button = MouseButtons.Left Then
                MouseMovePt = e.Location
                Invalidate()
            End If
        End Sub
    
        Private Sub Form3_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
    
            With e.Graphics
                .Clear(Color.Black)
                .SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
    
                Using p As New Pen(PenColor, 3)
                    p.DashStyle = Drawing2D.DashStyle.Dash
    
                    .DrawLine(p, MouseDownPt, MouseMovePt)
    
                End Using
            End With
        End Sub
    
        Private Sub Form3_Resize(sender As Object, e As EventArgs) Handles Me.Resize
            Invalidate()
        End Sub
    
    End Class

    Sunday, August 6, 2017 1:21 PM