I have a chart in Visual Studio 2013 and I can draw a line on it using the MouseventArgs handler. No worries.
But.... how can you have a separate subroutine that then uses the mouse events to draw a line. What I am need is if I hit a button, draw a line, if I did not hit the button use the regular mouseventargs.
So the button needs to start this:
enter code herePrivate Sub Chart1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles chD.MouseDown
FirstPoint = New Point(e.X, e.Y)
TempPoint = New Point(e.X, e.Y)
End Sub
Private Sub Chart1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles chD.MouseMove
If Not FirstPoint = Nothing Then
Dim g As Graphics = chD.CreateGraphics
Dim ErasePen As Pen = New Pen(Me.BackColor)
g.DrawLine(ErasePen, FirstPoint, TempPoint)
TempPoint = New Point(e.X, e.Y)
Me.Refresh()
End If
End Sub
Private Sub Chart1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles chD.MouseUp
Dim Line As New LineEndPoints With {.StartPoint = FirstPoint, .endPont = New Point(e.X, e.Y)}
LinesList.Add(Line)
FirstPoint = Nothing
Me.Refresh()
End Sub
Private Sub Chart1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles chD.Paint
For Each line As LineEndPoints In LinesList
e.Graphics.DrawLine(Pens.Yellow, line.StartPoint, line.endPont)
Next
If Not FirstPoint = Nothing Then
e.Graphics.DrawLine(Pens.Yellow, FirstPoint, TempPoint)
End If
End Sub`
`
Does anyone have any idea how I can achieve this?
Related
I want to draw a few lines on an image
Using mouse move in vb.net.
My problem is that when I start drawing the next line, the previous line disappears!
Can anyone help me?
I put my code along with a photo of run my project
Dim st, en As New Point
Dim p As Pen
Private mouseButtonPressed As Boolean = False
Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
p = New Pen(Color.Black, 2)
Dim g As Graphics = e.Graphics
g.DrawLine(p, st, en)
End Sub
Private Sub PictureBox1_MouseUp(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseUp
mouseButtonPressed = False
End Sub
Private Sub PictureBox1_MouseMove(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseMove
If mouseButtonPressed Then
PictureBox1.Invalidate()
en = e.Location
End If
End Sub
Private Sub PictureBox1_MouseDown(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseDown
If e.Button = MouseButtons.Left Then
st = New Point(e.X, e.Y)
mouseButtonPressed = True
End If
End Sub
You can store the lines in a list as they get completed, then draw all the previous lines when you are drawing the live one
Private st, en As New Point
Private mouseButtonPressed As Boolean = False
Private lines As New List(Of (st As Point, en As Point))
Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
Dim p = New Pen(Color.Black, 2)
Dim g As Graphics = e.Graphics
g.DrawLine(p, st, en)
For Each line In lines
g.DrawLine(p, line.st, line.en)
Next
End Sub
Private Sub PictureBox1_MouseUp(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseUp
mouseButtonPressed = False
lines.Add((st, en))
End Sub
Private Sub PictureBox1_MouseMove(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseMove
If mouseButtonPressed Then
PictureBox1.Invalidate()
en = e.Location
End If
End Sub
Private Sub PictureBox1_MouseDown(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseDown
If e.Button = MouseButtons.Left Then
st = New Point(e.X, e.Y)
mouseButtonPressed = True
End If
End Sub
The list holds Tuple(of Point, Point)
Im quite finished with my program, there are only 2 more things to do. But now lets focus on my main problem: Ive got a code, that gives the user the possibility to draw inside a picturebox, that will work later as a signature. Everything was working fine until I added a second picturebox with the same code( yes I changed for ex. picturebox1 to pixturebox2). As I start drawing I cant let go and both pictureboxes are getting interracted at the same time.
That my code for both pictureboxes.
Private _Previous As System.Nullable(Of Point) = Nothing
Private Sub pictureBox1_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles PictureBox1.MouseDown
_Previous = e.Location
pictureBox1_MouseMove(sender, e)
End Sub
Private Sub pictureBox1_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) Handles PictureBox1.MouseMove
If _Previous IsNot Nothing Then
If PictureBox1.Image Is Nothing Then
Dim bmp As New Bitmap(PictureBox1.Width, PictureBox1.Height)
Using g As Graphics = Graphics.FromImage(bmp)
g.Clear(Color.White)
End Using
PictureBox1.Image = bmp
End If
Using g As Graphics = Graphics.FromImage(PictureBox1.Image)
g.DrawLine(Pens.Black, _Previous.Value, e.Location)
End Using
PictureBox1.Invalidate()
_Previous = e.Location
End If
End Sub
Private Sub pictureBox2_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles PictureBox2.MouseDown
_Previous = e.Location
pictureBox1_MouseMove(sender, e)
End Sub
Private Sub pictureBox2_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) Handles PictureBox2.MouseMove
If _Previous IsNot Nothing Then
If PictureBox2.Image Is Nothing Then
Dim bmp As New Bitmap(PictureBox2.Width, PictureBox2.Height)
Using g As Graphics = Graphics.FromImage(bmp)
g.Clear(Color.White)
End Using
PictureBox2.Image = bmp
End If
Using g As Graphics = Graphics.FromImage(PictureBox2.Image)
g.DrawLine(Pens.Black, _Previous.Value, e.Location)
End Using
PictureBox2.Invalidate()
_Previous = e.Location
End If
End Sub
Private Sub pictureBox2_MouseUp(ByVal sender As Object, ByVal e As MouseEventArgs) Handles PictureBox2.MouseUp
_Previous = Nothing
End Sub
I know there is an mistake somewere, but Im to excited to see it.
In this event handler for PictureBox2 you call the handler for PictureBox1:
Private Sub pictureBox2_MouseDown(ByVal sender As Object, _
ByVal e As MouseEventArgs) Handles PictureBox2.MouseDown
_Previous = e.Location
pictureBox1_MouseMove(sender, e)
End Sub
I'm guessing changing it to:
pictureBox2_MouseMove(sender, e)
will fix it.
I am trying to have a button, when clicked, creates a new picturebox control. So that everytime I click it, it adds another new picturebox control. These pictureboxes will all have the same functions like being able to move them around and draw on them. But the button only makes one and no more after that with the following code. What am I missing?
Public Class Form1
Dim xpos As New Integer
Dim ypos As New Integer
Dim pos As New Point
Dim x As Integer
Dim y As Integer
Dim canvas As New PictureBox
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim i As Integer = 0
i = i + 1
canvas.Name = "canvas" & i
canvas.BackColor = Color.White
canvas.BorderStyle = BorderStyle.FixedSingle
canvas.Image = Nothing
canvas.Height = TextBox1.Text
canvas.Width = TextBox2.Text
AddHandler canvas.MouseDown, AddressOf PictureBox1_MouseDown
AddHandler canvas.MouseMove, AddressOf PictureBox1_MouseMove
Controls.Add(canvas)
End Sub
Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
xpos = Cursor.Position.X - canvas.Location.X
ypos = Cursor.Position.Y - canvas.Location.Y
End Sub
Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
If e.Button = Windows.Forms.MouseButtons.Left Then
pos = MousePosition
pos.X = pos.X - xpos
pos.Y = pos.Y - ypos
canvas.Location = pos
End If
End Sub
Private Sub PictureBox1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
End Sub
End Class
Dim canvas As New PictureBox
You have multiple bugs in your code but this is the most serious one. The As New syntax ensures that you'll always create a PictureBox object, but it will only ever be one object. And of course, one variable cannot keep track of multiple picture boxes.
What you need to do is create a new one ever time the button is clicked. It is generally a good idea to keep track of the picture boxes you create. So correct code looks like:
Dim canvases As New List(Of PictureBox)
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim canvas = New PictureBox
canvases.Add(canvas)
canvas.Name = "canvas" & canvases.Count.ToString()
'' etc...
End Sub
Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
Dim canvas = DirectCast(sender, PictureBox)
xpos = Cursor.Position.X - canvas.Location.X
ypos = Cursor.Position.Y - canvas.Location.Y
End Sub
Note how the sender argument gives you a reference back to the picture box object that's being moused. Do the same thing in any other event handlers.
Increasing the counter whenever a new canvas is created:
Public Class Form1
Dim counter As New Integer
...
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
counter += 1
canvas.Name = "canvas" & counter.ToString()
...
Accessing the canvas that the mouse is currently moving over:
Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
If e.Button = Windows.Forms.MouseButtons.Left Then
pos = MousePosition
pos.X = pos.X - xpos
pos.Y = pos.Y - ypos
DirectCast(sender, PictureBox).Location = pos
End If
End Sub
I'm trying to move picture boxes in a panel.
This is my Code:
Private dragging As Boolean
Private beginX, beginY As Integer
Private Sub Control_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
dragging = True
beginX = CType(sender, PictureBox).Location.X
beginY = CType(sender, PictureBox).Location.Y
End Sub
Private Sub Control_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
Dim cntrl As Control = CType(sender, Control)
If dragging = True Then
cntrl.Location = New Point(cntrl.Location.X + e.X - beginX, cntrl.Location.Y + e.Y - beginY)
'Me.Refresh()
End If
End Sub
Private Sub Control_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
dragging = False
End Sub
I can't figure out why this don't work.
The subroutines you have are missing their handlers (ie the handles statement) at the end.
ex:
Private Sub Control_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) HANDLES controlName.MouseUp
dragging = False
End Sub
Try this:
Dim cmd As Boolean = False
Dim sp As Point
Private Sub Form1_Load() Handles MyBase.Load
For Each Control As Picturebox In Me.Controls.OfType(Of Picturebox)
AddHandler Control.MouseDown, Sub(sender As Object, e As MouseEventArgs)
cmd = True
sp = e.Location
End Sub
AddHandler Control.MouseMove, Sub(sender As Object, e As MouseEventArgs)
If cmd Then
Control.Location = Control.Location - sp + e.Location
End If
End Sub
AddHandler Control.MouseUp, Sub(sender As Object, e As MouseEventArgs)
cmd = False
End Sub
Next
End Sub
I am working on a simple VB interface that should allow the user to draw a line from the point the mouse is clicked down to whereever the mouse position is, then leave the line where the mouse button is released. I am new to VB GDI+ and could use some pointers or tips. I need it so that I can draw multiple lines on the same control panel and everytime I start a new line somehow make it that the Paint paint function does not have to loop through each line I already drew. Here is my Code:
Public Class Form1
Dim down = False
Dim ptA As Point
Dim ptB As Point
Dim ptC As Point
Dim ptStart As New List(Of Point) ' Starting point of each line
Dim ptEnd As New List(Of Point) ' Ending Point of Each line
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.DoubleBuffered = True
End Sub
Private Sub Win_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Win.MouseDown
down = True
ptA = New Point(e.X, e.Y)
End Sub
Private Sub Win_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Win.MouseMove
If down = True Then
ptB = New Point(e.X, e.Y)
Win.Invalidate()
End If
End Sub
Private Sub Win_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Win.MouseUp
down = False
ptC = New Point(e.X, e.Y)
ptStart.Add(ptA)
ptEnd.Add(ptC)
End Sub
Private Sub Win_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Win.Paint
e.Graphics.Clear(Color.Black)
e.Graphics.DrawLine(Pens.LawnGreen, ptA, ptB)
For i = 0 To ptStart.Count - 1
Win.CreateGraphics.DrawLine(Pens.LawnGreen, ptStart(i), ptEnd(i))
Next
End Sub
End Class
In order to keep my existing lines, I stored the points in a list and each time I move the mouse while drawing, I call the Paint function and each time it is called, it loops through each point and draws a line between them. Any suggestions would be greatly appreciated.
Thank you,
JD
** Edit
Public Class Form1
Dim down = False
Dim ptA As Point
Dim ptB As Point
Dim ptC As Point
Dim ptStart As New List(Of Point)
Dim ptEnd As New List(Of Point)
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.DoubleBuffered = True
End Sub
Private Sub Win_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Win.MouseDown
down = True
ptA = New Point(e.X, e.Y)
End Sub
Private Sub Win_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Win.MouseMove
If down = True Then
ptB = New Point(e.X, e.Y)
Win.Invalidate()
End If
End Sub
Private Sub Win_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Win.MouseUp
down = False
ptC = New Point(e.X, e.Y)
ptStart.Add(ptA)
ptEnd.Add(ptC)
End Sub
Private Sub Win_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Win.Paint
e.Graphics.Clear(Color.Black)
e.Graphics.DrawLine(Pens.LawnGreen, ptA, ptB)
For i = 0 To ptStart.Count - 1
e.Graphics.DrawLine(Pens.LawnGreen, ptStart(i), ptEnd(i))
Next
End Sub
End Class