Link to home
Start Free TrialLog in
Avatar of jfyfe
jfyfe

asked on

drawing lines using the mouse on images

Hi.

I have several Picture boxes located on a Panel control.  In the picture boxes are stock charts.  I would like to draw "trendlines" across these charts using the mouse while the application is running.  I'd also like to learn more about drawing more complicated lines (such as a fibbonaci retracement) when I learn more.

If someone could provide code or a link that discusses this or at least gets me started, I appreciate it.  Thanks.
Avatar of Mike Tomlinson
Mike Tomlinson
Flag of United States of America image

Here is an example that allows FREEHAND style drawings on a PictureBox:

Public Class Form1

    Private paths As New ArrayList
    Private gp As System.Drawing.Drawing2D.GraphicsPath
    Private lastPoint As Point

    Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
        If e.Button = Windows.Forms.MouseButtons.Left Then
            gp = New System.Drawing.Drawing2D.GraphicsPath
            paths.Add(gp)
            lastPoint = New Point(e.X, e.Y)
        End If
    End Sub

    Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
        If e.Button = Windows.Forms.MouseButtons.Left Then
            Dim curPoint As New Point(e.X, e.Y)
            gp.AddLine(lastPoint, curPoint)
            lastPoint = curPoint
            PictureBox1.Refresh()
        End If
    End Sub

    Private Sub PictureBox1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp
        If e.Button = Windows.Forms.MouseButtons.Left Then
            PictureBox1.Refresh()
        End If
    End Sub

    Private Sub PictureBox1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
        Dim gp As System.Drawing.Drawing2D.GraphicsPath
        Dim g As Graphics = e.Graphics
        For Each gp In paths
            g.DrawPath(Pens.Black, gp)
        Next
    End Sub

End Class
Avatar of jfyfe
jfyfe

ASKER

Thank you.  That was a little helpful.  But, I need more help though.  If you can help me do two things:  

1) I need a straight line from the mouse down event until the mouse up event.   So that instead of a scribbly line, a straight line is created.  Will add 125 pts for this.

2) (I don't know if this is possible), but I need to draw ACROSS different picture boxes, not just within one picture box.  I have about seven picture boxes in a panel control stacked one on top of the other.  I would like to, for example, draw a verticle line across all seven picture boxes.
Will add 250 points for this.

Thanks.
ASKER CERTIFIED SOLUTION
Avatar of Mike Tomlinson
Mike Tomlinson
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Number #2 is in fact possible, but I don't know if you want to deal with the headache involved...

The problem is that to make a line go OVER multiple controls you have to draw using low level APIs using either the containers or the desktops DC.  Then, to make matters complicated, if the PictureBoxes refresh themselves, the line will disappear inside the PBs as the charts get drawn.  We would have to do some low level tracking to make sure we paint the lines after all child controls paint themselves or use some UGLY timer code to constantly redraw the lines so it just doesn't matter if they get erased.

One way around this is to NOT use multiple PictureBoxes.  Instead you could either:

    (1) Make one big composite Image from the multiple charts, assign that image to a PictureBox, and use the code above.

    (2) Draw each chart manually in the Paint() event at different positions in a PictureBox and then use the code above.

Avatar of jfyfe

ASKER

Thank you.  I appreciate the help and your suggestions for improvement.  You made it very easy for me to implement.  I will take your advice on combining the images into one picture box.

If its not too much trouble is there a fast way to remove the graphics, on a button click?
To empty a PictureBox?

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        PictureBox1.Image = Nothing
    End Sub

Do you need help with the code to combine the images?
No...silly me...you probably meant how to remove the lines in my code:

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        lines.Clear()
        PictureBox1.Refresh()
    End Sub
Avatar of jfyfe

ASKER

Thanks alot Idle Mind!  I will play around with combining images (for a little while at least), and when I need help, I will post it in a new question.