I have a class that changes the mouse event args of a picturebox and allows the user to resize it during runtime. I am trying to add a checkbox for each picturebox that will maintain the aspect ratio of the picturebox when the checkbox is checked.
I can get it to work if I add the code separately for each checkbox on the form but I want to keep it in a separate class so that it works for any checkbox.
Here is the code for the class to resize the pictureboxes
Public Class ResizeableControl
Public WithEvents mControl As Control
Public mPreserveAspectRatio As Boolean
Dim AtRightEdge As Boolean = False
Dim AtBottomEdge As Boolean = False
Dim InBoxWidth As Boolean = False
Dim InBoxHeight As Boolean = False
Dim DraggingHorizontal As Boolean
Dim DraggingVerticle As Boolean
Dim DraggingCorner As Boolean
Const DragMarginWidth As Integer = 6
Const DragMarginHeight As Integer = 6
Public dragOrigin As Point
Dim MoveBox As Boolean = False
Dim LastPos As Point
Public Sub New(ByVal Control As Control, ByVal preserveAspectRatio As Boolean)
mControl = Control
mPreserveAspectRatio = preserveAspectRatio
End Sub
Private Sub mControl_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles mControl.MouseMove
If MoveBox Then
Dim movement As Point = Cursor.Position
' move image by the distance the mouse moved hoizontally and vertically
movement.Offset(-LastPos.X, -LastPos.Y)
mControl.Location = movement
ElseIf DraggingHorizontal Then
Dim movement As Point = New Point(e.X - dragOrigin.X, e.Y - dragOrigin.Y) 'How far did the mouse move? (Distance = newPoint - oldPoint)
If mPreserveAspectRatio = True Then
mControl.Width += movement.X 'Change width of the image by the distance the mouse moved
mControl.Height = Math.Round((Convert.ToDouble(mControl.Width) / 6.0) * 4.0)
Else
mControl.Width += movement.X 'Change width of the image by the distance the mouse moved
End If
dragOrigin = e.Location 'Next time we will measure from the now-current mouse position
ElseIf DraggingVerticle Then
Dim movement As Point = New Point(e.X - dragOrigin.X, e.Y - dragOrigin.Y)
If mPreserveAspectRatio = True Then
mControl.Height += movement.Y 'Change height of the image by the distance the mouse moved
mControl.Width = Math.Round((Convert.ToDouble(mControl.Height) / 4.0) * 6.0)
Else
mControl.Height += movement.Y 'Change height of the image by the distance the mouse moved
End If
dragOrigin = e.Location
ElseIf DraggingCorner Then
Dim movement As Point = New Point(e.X - dragOrigin.X, e.Y - dragOrigin.Y)
If mPreserveAspectRatio = True Then
' Resize the image by the distance the mouse moved hoizontally and vertically
mControl.Height += movement.Y
mControl.Width += movement.X
mControl.Height = Math.Round((Convert.ToDouble(mControl.Width) / 6.0) * 4.0)
mControl.Width = Math.Round((Convert.ToDouble(mControl.Height) / 4.0) * 6.0)
Else
' Resize the image by the distance the mouse moved hoizontally and vertically
mControl.Height += movement.Y
mControl.Width += movement.X
End If
dragOrigin = e.Location
Else
' Is mouse within right six-or-so pixels?
AtRightEdge = e.X > (mControl.Width - DragMarginWidth)
' Is mouse within bottom six-or-so pixels?
AtBottomEdge = e.Y > (mControl.Height - DragMarginHeight)
' Is mouse within the box?
InBoxWidth = e.X < (mControl.Width - DragMarginWidth)
InBoxHeight = e.Y < (mControl.Height - DragMarginHeight)
' Set the cursor accordingly
If (AtBottomEdge And AtRightEdge) Then
mControl.Cursor = Cursors.SizeNWSE
ElseIf (InBoxWidth And InBoxHeight) Then
mControl.Cursor = Cursors.SizeAll
ElseIf (AtBottomEdge) Then
mControl.Cursor = Cursors.SizeNS
ElseIf (AtRightEdge) Then
mControl.Cursor = Cursors.SizeWE
Else
mControl.Cursor = Cursors.Default
End If
End If
End Sub
Private Sub mControl_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles mControl.MouseDown
' If the user presses the mouse button at the bottom right corner, begin dragging
If (InBoxWidth And InBoxHeight) Then
Dim movement As Point = Cursor.Position
movement.Offset(-mControl.Location.X, -mControl.Location.Y)
LastPos = movement
MoveBox = True
ElseIf (AtBottomEdge And AtRightEdge) Then
dragOrigin = e.Location
DraggingCorner = True
ElseIf AtRightEdge Then
dragOrigin = e.Location
DraggingHorizontal = True
ElseIf AtBottomEdge Then
dragOrigin = e.Location
DraggingVerticle = True
End If
End Sub
Private Sub mControl_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles mControl.MouseUp
' Stop dragging
MoveBox = False
DraggingHorizontal = False
DraggingVerticle = False
DraggingCorner = False
End Sub
Private Sub mControl_MouseLeave(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mControl.MouseLeave
MoveBox = False
DraggingHorizontal = False
DraggingVerticle = False
DraggingCorner = False
mControl.Cursor = Cursors.Default
End Sub
End Class
I create a new instance of the class for each picturebox (I have just 2 here to keep it simple but have more) when the form loads but then I can't figure out how to change the aspect ratio boolean (mPreserveAspectRatio). I have tried just changing the boolean when the checkbox changes states but that doesn't work. And I think I may need to somehow create a public method to change the boolean but can't wrap my head around it. Here is the latest code I have been trying that doesn't work
Imports WindowsApplication1.ResizeableControl
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim mControl As New ResizeableControl(PictureBox1, True)
Dim mControl2 As New ResizeableControl(PictureBox2, True)
End Sub
Private Sub CheckBox1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox1.CheckedChanged
If CheckBox1.Checked Then
Dim mControl1 As New ResizeableControl(PictureBox1, True)
Else
Dim mControl1 As New ResizeableControl(PictureBox1, False)
End If
End Sub
Private Sub CheckBox2_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox2.CheckedChanged
If CheckBox2.Checked Then
Dim mControl1 As New ResizeableControl(PictureBox2, True)
Else
Dim mControl1 As New ResizeableControl(PictureBox2, False)
End If
End Sub
End Class
I figured it out. You pointed me in the right direction Jeff. I did need to add the control to the form. Here is what I did.
Imports WindowsApplication1.ResizeableControl
Public Class Form1
Dim mControl1 As New ResizeableControl(PictureBox1, True)
Dim mControl2 As New ResizeableControl(PictureBox2, True)
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim Control1 As New ResizeableControl(PictureBox1, True)
Me.mControl1 = Control1
Dim Control2 As New ResizeableControl(PictureBox2, True)
Me.mControl2 = Control2
End Sub
Private Sub CheckBox1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox1.CheckedChanged
If CheckBox1.Checked Then
Me.mControl1.mPreserveAspectRatio = True
Else
Me.mControl1.mPreserveAspectRatio = False
End If
End Sub
Private Sub CheckBox2_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox2.CheckedChanged
If CheckBox2.Checked Then
Me.mControl2.mPreserveAspectRatio = True
Else
Me.mControl2.mPreserveAspectRatio = False
End If
End Sub
End Class
Related
I am trying to assign two clicks to two variables on my Mouse_Down event on my form. Here is the starting code I am working with on Mouse_Down event. What I am trying to do is click two points on a form, get the X & Y location (these will then give me my button size). Example: First Click get X & Y, Second Click get X & Y then perform click of a button.... repeat this until I quit.
Private Sub Form1_MouseDown(sender As Object, e As MouseEventArgs) Handles MyBase.MouseDown
Dim XYClickOne, XYClickTwo
Dim count As Integer
count = 0
Do
XYClickOne = e.X & "," & e.Y
XYClickTwo = e.X & "," & e.Y
count = count + 1
Loop Until count = 2
Button1.PerformClick() 'After 2nd click, create button.
End Sub
Move those variables out to Form level so they are accessible by other methods, and will persist across clicks. Here's a quick example:
Public Class Form1
Private points(2) As Point
Private count As Integer = 0
Private Sub Form1_MouseDown(sender As Object, e As MouseEventArgs) Handles Me.MouseDown
If e.Button = MouseButtons.Left Then
points(count) = New Point(e.X, e.Y)
count = count + 1
If count = 2 Then
count = 0
CreateButton(points(0), points(1))
End If
End If
End Sub
Private Sub CreateButton(ByVal ptA As Point, ByVal ptB As Point)
Dim pt As New Point(Math.Min(ptA.X, ptB.X), Math.Min(ptA.Y, ptB.Y))
Dim sz As New Size(Math.Abs(ptA.X - ptB.X) + 1, Math.Abs(ptA.Y - ptB.Y) + 1)
Dim btn As New Button
btn.Bounds = New Rectangle(pt, sz)
btn.Text = "X"
Me.Controls.Add(btn)
End Sub
End Class
Thought you might like a quick example of making a "rubber band selection". Click and DRAG on your form with the left mouse button:
The artifacts are from my screen recorder, in reality it drew smoothly with out leaving lines behind:
Code:
Public Class Form1
Private ptA, ptB As Point
Private count As Integer = 0
Private firstBoxDrawn As Boolean = False
Private Sub Form1_MouseDown(sender As Object, e As MouseEventArgs) Handles Me.MouseDown
If e.Button = MouseButtons.Left Then
ptA = Me.PointToScreen(New Point(e.X, e.Y))
ptB = ptA
firstBoxDrawn = False
End If
End Sub
Private Sub Form1_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove
If e.Button = MouseButtons.Left Then
If firstBoxDrawn Then
' erase the previous box by drawing it again
ControlPaint.DrawReversibleFrame(RectangleFromPoints(ptA, ptB), Color.Black, FrameStyle.Dashed)
End If
ptB = Me.PointToScreen(New Point(e.X, e.Y))
' draw the new box
ControlPaint.DrawReversibleFrame(RectangleFromPoints(ptA, ptB), Color.Black, FrameStyle.Dashed)
firstBoxDrawn = True
End If
End Sub
Private Sub Form1_MouseUp(sender As Object, e As MouseEventArgs) Handles Me.MouseUp
If e.Button = MouseButtons.Left Then
' erase the box
ControlPaint.DrawReversibleFrame(RectangleFromPoints(ptA, ptB), Color.Black, FrameStyle.Dashed)
CreateButton(Me.PointToClient(ptA), Me.PointToClient(ptB))
End If
End Sub
Private Sub CreateButton(ByVal ptA As Point, ByVal ptB As Point)
Dim btn As New Button
btn.Text = "X"
btn.Bounds = RectangleFromPoints(ptA, ptB)
Me.Controls.Add(btn)
End Sub
Private Function RectangleFromPoints(ByVal ptA As Point, ByVal ptB As Point) As Rectangle
Dim pt As New Point(Math.Min(ptA.X, ptB.X), Math.Min(ptA.Y, ptB.Y))
Dim sz As New Size(Math.Abs(ptA.X - ptB.X) + 1, Math.Abs(ptA.Y - ptB.Y) + 1)
Return New Rectangle(pt, sz)
End Function
End Class
This solution seems to be the best one out there and the most commonly accepted one - however, if you scroll to the bottom and touch a the actual flowcontrol behind the buttons (I tried to make this so that there would be empty space to make this sample test easier), you then have to double tap-and-hold the button for the scrolling to resume. Restarting the application restores the phone-like scrolling functionality. I am wondering if anyone else has seen this or figured it out - try it with your apps and see if it is the case as well. I modified the snippet above so that you can start a new project, copy and paste this into form1's code, and hit run.
Public Class Form1
Dim FlowPanel As New FlowLayoutPanel
Private Function GenerateButton(ByVal pName As String) As Button
Dim mResult As New Button
With mResult
.Name = pName
.Text = pName
.Width = 128
.Height = 128
.Margin = New Padding(0)
.Padding = New Padding(0)
.BackColor = Color.CornflowerBlue
AddHandler .MouseDown, AddressOf Button_MouseDown
AddHandler .MouseMove, AddressOf Button_MouseMove
End With
Return mResult
End Function
Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
Me.Width = 806
Me.Height = 480
FlowPanel.Padding = New Padding(0)
FlowPanel.Margin = New Padding(0)
' FlowPanel.ColumnCount = Me.Width / (128 + 6)
FlowPanel.Dock = DockStyle.Fill
FlowPanel.AutoScroll = True
Me.Controls.Add(FlowPanel)
Dim i As Integer
For i = 1 To 98
FlowPanel.Controls.Add(GenerateButton("btn" & i.ToString))
Next
End Sub
Dim myMouseDownPoint As Point
Dim myCurrAutoSMouseDown As Point
Private Sub Button_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
myMouseDownPoint = PointToClient(Cursor.Position)
myCurrAutoSMouseDown = FlowPanel.AutoScrollPosition
End Sub
Private Sub Button_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)
If e.Button = Windows.Forms.MouseButtons.Left Then
Dim mLocation As Point = PointToClient(Cursor.Position)
If myMouseDownPoint <> mLocation Then
Dim mCurrAutoS As Point
Dim mDeslocation As Point = myMouseDownPoint - mLocation
mCurrAutoS.X = Math.Abs(myCurrAutoSMouseDown.X) + mDeslocation.X
mCurrAutoS.Y = Math.Abs(myCurrAutoSMouseDown.Y) + mDeslocation.Y
FlowPanel.AutoScrollPosition = mCurrAutoS
End If
End If
End Sub
End Class
Thanks for the code , I made some changes to improve behavior . I hope it can be useful to someone .
Dim myMouseDownPoint As Point
Dim myCurrAutoSMouseDown As Point
'Add boolean variable a true.
Private _ValidateClickEvent As Boolean = True
Private Sub MyMouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
myMouseDownPoint = PointToClient(Cursor.Position)
myCurrAutoSMouseDown = Panel1.AutoScrollPosition
End Sub
' Add MouseUp event for return the boolean variable a true.
Private Sub MyMouseUp(ByVal sender As Object, ByVal e As MouseEventArgs)
_ValidateClickEvent = True
End Sub
'Set boolean variable a false when change mlocation.
Private Sub MyMouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)
If e.Button = Windows.Forms.MouseButtons.Left Then
Dim mLocation As Point = PointToClient(Cursor.Position)
If myMouseDownPoint <> mLocation Then
Dim mCurrAutoS As Point
Dim mDeslocation As Point = CType(myMouseDownPoint - mLocation, Size)
mCurrAutoS.X = Math.Abs(myCurrAutoSMouseDown.X) + mDeslocation.X
mCurrAutoS.Y = Math.Abs(myCurrAutoSMouseDown.Y) + mDeslocation.Y
Panel1.AutoScrollPosition = mCurrAutoS
_ValidateClickEvent = False
End If
End If
End Sub
' Test boolean variable to perform click event.
Private Sub MyClick(sender As System.Object, e As System.EventArgs)
If _ValidateClickEvent Then
........................
Else
_ValidateClickEvent = True
End If
End Sub
So my problem is that I want to have multiple rectangles on a form at a time. However I also want these rectangles to be able to be clicked and dragged across the form.
This is my current code for clicking and dragging a rectangle that was drawn onto the form using the toolbox.
Public Class DragRectangle
Dim Go As Boolean
Dim LeftSet As Boolean
Dim TopSet As Boolean
Dim HoldLeft As Integer
Dim HoldTop As Integer
Dim OffLeft As Integer
Dim OffTop As Integer
Private Sub obj1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles RectangleShape1.MouseUp
Go = False
LeftSet = False
TopSet = False
End Sub
Private Sub obj1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles RectangleShape1.MouseDown
Go = True
End Sub
Private Sub obj1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles RectangleShape1.MouseMove
If Go = True Then
HoldLeft = (Control.MousePosition.X - Me.Left)
HoldTop = (Control.MousePosition.Y - Me.Top)
If TopSet = False Then
OffTop = HoldTop - sender.Top
TopSet = True
End If
If LeftSet = False Then
OffLeft = HoldLeft - sender.Left
LeftSet = True
End If
sender.Left = HoldLeft - OffLeft
sender.Top = HoldTop - OffTop
End If
End Sub
End Class
This works fine for one rectangle, although this requires the rectangles to be pre-drawn onto the form using the toolbox.
What I would like is a rectangle gets drawn by clicking a button on the form, and the newly drawn rectangle can also be clicked and dragged into a new location.
Is this possible?
Thanks for any help
Working example:
Public Class Form1
Private Property Rectangles As New List(Of DrgRectangle)
Private Property curRect As DrgRectangle
Private _x As Integer
Private _y As Integer
Private Sub loadme() Handles Me.Load
'load the rectangle in list
Rectangles.Add(New DrgRectangle With {.Rect = New Rectangle(20, 20, 20, 20)})
End Sub
Private Sub FormMouseDown(sender As Object, e As MouseEventArgs) Handles Me.MouseDown
_x = e.X
_y = e.Y
For Each rect In Rectangles
If rect.Rect.Contains(e.X, e.Y) Then
curRect = rect
Exit For
End If
Next
End Sub
Private Sub FormMouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove
If e.Button = Windows.Forms.MouseButtons.Left Then
If curRect IsNot Nothing Then
curRect.Rect = New Rectangle(New Point(curRect.Rect.Location.X + (e.X - _x), curRect.Rect.Location.Y + (e.Y - _y)), curRect.Rect.Size)
Me.Refresh()
End If
End If
_x = e.X
_y = e.Y
End Sub
Private Sub FormPaint(sender As Object, e As PaintEventArgs) Handles me.Paint
For Each rect In Rectangles
e.Graphics.DrawRectangle(Pens.Black, rect.Rect)
Next
End Sub
End Class
Public Class DrgRectangle
Public Rect As New Rectangle
'add more properties as needed
End Class
I want to drag the control which is in inside the panel. So first i tried change the parent of control panel to form in mouse down after that i drag it. But its not drag smoothly. If the control is in form and drag the control its drag smoothly what is difference? how to solve it?.
My code is :
Private cachedMousePos As Point
Private cachedControlPos As Point
Private isMouseDown As Boolean
Private Sub HandleDraggableControlMouseDown(ByVal sender As Object, ByVal e As
MouseEventArgs) Handles Button1.MouseDown
Dim target As Control = TryCast(sender, Control)
If (Not target Is Nothing) Then
Dim pt As Point = Me.PointToClient(target.PointToScreen(Point.Empty))
target.Dock = DockStyle.None
target.Parent = Me
target.BringToFront()
target.Location = pt
Me.isMouseDown = True
Me.cachedControlPos = pt
Me.cachedMousePos = Control.MousePosition
End If
End Sub
Private Sub HandleDraggableControlMouseMove(ByVal sender As Object, ByVal e As
MouseEventArgs) Handles Button1.MouseMove
If (Me.isMouseDown) Then
Dim target As Control = TryCast(sender, Control)
If (Not target Is Nothing) Then
Dim x As Integer = (Me.cachedControlPos.X + (Control.MousePosition.X -
Me.cachedMousePos.X))
Dim y As Integer = (Me.cachedControlPos.Y + (Control.MousePosition.Y -
Me.cachedMousePos.Y))
target.Location = New Point(x, y)
'c2 = (c1 + (m2 - m1))
End If
End If
End Sub
Private Sub HandleDraggableControlMouseUp(ByVal sender As Object, ByVal e As
MouseEventArgs) Handles Button1.MouseUp
Me.cachedControlPos = Point.Empty
Me.cachedMousePos = Point.Empty
Me.isMouseDown = False
End Sub
I'm trying to draw a triangle like this:
Dim triangle As Graphics
Dim pen1 As New Pen(Color.LimeGreen, 2)
Dim lside As Integer
Dim wside As Integer
Dim dside As Integer
triangle = Me.CreateGraphics()
triangle.DrawLine(pen1, wside, 420, 640, 420)
triangle.DrawLine(pen1, 640, lside, 640, 420)
triangle.DrawLine(pen1, dside, 420, 640, lside)
lside, wside and dside stand for length side, width side and diagonal side.
I've got 4 textboxes, for the length, width, diagonal side and one for the angle.
The purpose is to fill in 2 of the values, and then a rectangular triangle gets drawn following Pythagoras' theorem. I want to draw a line for Angle as well later on. But I first want to get this to work.
But every time I click the button to draw a new triangle, the previous one should get deleted. And that's the problem.
I've tried multiple methods, like triangle.Dispose triangle.Restore triangle.Clear and more. None of them work.
Why am I not drawing them in a picturebox you might ask. Well, when I drew a line in a picturebox, the picturebox sort of went in front of the line, making the line invisible. And I didn't know how to fix that.
Try using Me.Invalidate(), it basically clears, then draws the shape in the area you're painting on. Reference.
Private Sub ClearCanvas_Click(sender As Object, e As EventArgs) Handles Button1.Click
Me.Invalidate()
End Sub
Priavte DrawTriangle_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim triangle As Graphics
Dim pen1 As New Pen(Color.LimeGreen, 2)
Dim lside As Integer
Dim wside As Integer
Dim dside As Integer
triangle = Me.CreateGraphics()
triangle.DrawLine(pen1, wside, 420, 640, 420)
triangle.DrawLine(pen1, 640, lside, 640, 420)
triangle.DrawLine(pen1, dside, 420, 640, lside)
End Sub
‘Draw select delete multiple lines on Picturebox
Imports System
Imports System.Drawing
Imports System.Drawing.Drawing2D
Public Class Form1
Dim drawrec, undo_delete As Boolean
Dim index_arrary_line_tobe_deleted(10000) As Integer
Dim ptA, ptB As Point ' starting and ending point
Dim down As Boolean
Dim k, Last_index_line_tobe_selected As Integer
Private temp As line
Dim List_of_line_tobe_deleted As New List(Of line)
Dim List_of_line_to_Undo As New List(Of line)
Private m_Lines As New List(Of line)
Private m_Pt As Point
Private m_Pt2 As Point
Private m_tracking As Boolean
Private Sub B2_index_arrary_line_tobe_deletedete_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles B2_Delete.Click
Try
m_Lines.RemoveAll(AddressOf List_of_line_tobe_deleted.Contains)
Catch ex As Exception
End Try
PictureBox1.Refresh()
End Sub
Private Sub B3_Undodelete_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles B3_Undodelete.Click
undo_delete = True
Try
m_Lines.AddRange(List_of_line_tobe_deleted)
Catch ex As Exception
End Try
PictureBox1.Refresh()
End Sub
Private Sub B1_Select_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles B1_Select.Click
drawrec = True
End Sub
Private Sub PictureBox1_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles PictureBox1.Paint
Dim r As New Rectangle(m_Pt, New Size(m_Pt2.X - m_Pt.X, m_Pt2.Y - m_Pt.Y))
If m_tracking = True And drawrec = True Then
k = -1
For i As Integer = 0 To m_Lines.Count - 1
If m_Lines(i).ContainsCompletely(r) = True Then
k = k + 1
index_arrary_line_tobe_deleted(i) = k
Debug.Print("Index of NOT selected lines " + i.ToString + "Index of selected lines " + Last_index_line_tobe_selected.ToString) 'to compare idex of two lists !!!!
index_arrary_line_tobe_deleted(k) = i
List_of_line_tobe_deleted.Add(m_Lines(i))
End If
Next
Last_index_line_tobe_selected = k 'so far no use, just to know
e.Graphics.DrawRectangle(Pens.Cyan, r)
End If
If undo_delete = False Then
For i As Integer = 0 To m_Lines.Count - 1
Me.m_Lines(i).Draw(e.Graphics, r)
Debug.Print("Index of remaining lines " + i.ToString)
Next
End If
If undo_delete = True Then
For i As Integer = 0 To m_Lines.Count - 1
Me.m_Lines(i).Re_Draw(e.Graphics)
Debug.Print("Index of remaining lines " + i.ToString)
Next
End If
End Sub
Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
drawrec = False
down = False
undo_delete = False
For i As Integer = 0 To index_arrary_line_tobe_deleted.Length - 1
index_arrary_line_tobe_deleted(0) = -1
Next i
k = -1
Last_index_line_tobe_selected = -1
End Sub
Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles PictureBox1.MouseDown
down = True
If down = True And drawrec = False Then
ptA = e.Location
temp = New line
temp.StartPoint = e.Location
End If
If e.Button = MouseButtons.Left Then
ResetSelected(Me.m_Lines)
m_Pt = e.Location
End If
End Sub
Private Sub ResetSelected(ByVal m_Lines As List(Of line))
For i As Integer = 0 To m_Lines.Count - 1
m_Lines(i).Selected = False
Next
End Sub
Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) Handles PictureBox1.MouseMove
If down = True Then
End If
If e.Button = MouseButtons.Left Then
If down = True And drawrec = False Then
ptB = e.Location
temp.EndPoint = e.Location
End If
m_Pt2 = e.Location
m_tracking = True
Me.PictureBox1.Invalidate()
End If
End Sub
Private Sub PictureBox1_MouseUp(ByVal sender As Object, ByVal e As MouseEventArgs) Handles PictureBox1.MouseUp
down = False
If drawrec = False Then
temp.EndPoint = e.Location
m_Lines.Add(temp)
temp = Nothing
Me.PictureBox1.Invalidate()
End If
m_tracking = False
Me.PictureBox1.Invalidate()
End Sub
End Class
Public Class line
Public StartPoint As Point
Public EndPoint As Point
Private m_selected As Boolean
Public Property Selected() As Boolean
Get
Return m_selected
End Get
Set(ByVal value As Boolean)
m_selected = value
End Set
End Property
Public Sub Draw(ByVal g As Graphics, ByVal r As Rectangle)
Dim myPen1 As New Pen(Color.Red, 1)
g.SmoothingMode = SmoothingMode.AntiAlias
If Me.ContainsCompletely(r) OrElse Me.Selected Then
Me.Selected = True
g.DrawLine(myPen1, Me.StartPoint, Me.EndPoint)
Else
Dim myPen2 As New Pen(Color.Blue, 1)
g.DrawLine(myPen2, Me.StartPoint, Me.EndPoint)
End If
End Sub
Public Sub Re_Draw(ByVal g As Graphics)
g.SmoothingMode = SmoothingMode.AntiAlias
Dim myPen2 As New Pen(Color.Blue, 1)
g.DrawLine(myPen2, Me.StartPoint, Me.EndPoint)
End Sub
Public Function ContainsCompletely(ByVal r As Rectangle) As Boolean
If r.Contains(Me.StartPoint) AndAlso r.Contains(Me.EndPoint) Then
Return True
End If
Return False
End Function
End Class
Imports System
Imports System.Drawing
Imports System.Drawing.Drawing2D
Public Class Form1
Dim drawrec As Boolean
Dim del As Integer
Dim ptA, ptB As Point ' starting and ending point
Dim down As Boolean
Private temp As line
Private m_Lines As New List(Of line)
Private m_rnd As New Random
Private m_Pt As Point
Private m_Pt2 As Point
Private m_tracking As Boolean
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Bt_Delete.Click
Try
m_Lines.RemoveAt(del)
Catch ex As Exception
End Try
PictureBox1.Refresh()
End Sub
Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
drawrec = False
down = False
del = -1
End Sub
Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles PictureBox1.MouseDown
down = True
If down = True And drawrec = False Then
ptA = e.Location
temp = New line
temp.StartPoint = e.Location
End If
If e.Button = MouseButtons.Left Then
ResetSelected(Me.m_Lines)
m_Pt = e.Location
End If
End Sub
Private Sub ResetSelected(ByVal m_Lines As List(Of line))
For i As Integer = 0 To m_Lines.Count - 1
m_Lines(i).Selected = False
Next
End Sub
Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) Handles PictureBox1.MouseMove
If down = True Then
End If
If e.Button = MouseButtons.Left Then
If down = True And drawrec = False Then
ptB = e.Location
temp.EndPoint = e.Location
End If
m_Pt2 = e.Location
m_tracking = True
Me.PictureBox1.Invalidate()
End If
End Sub
Private Sub PictureBox1_MouseUp(ByVal sender As Object, ByVal e As MouseEventArgs) Handles PictureBox1.MouseUp
down = False
If drawrec = False Then
temp.EndPoint = e.Location
m_Lines.Add(temp)
temp = Nothing
Me.PictureBox1.Invalidate()
End If
m_tracking = False
Me.PictureBox1.Invalidate()
End Sub
Private Sub PictureBox1_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles PictureBox1.Paint
Dim r As New Rectangle(m_Pt, New Size(m_Pt2.X - m_Pt.X, m_Pt2.Y - m_Pt.Y))
If m_tracking And drawrec = True Then
For i As Integer = 0 To m_Lines.Count - 1
If m_Lines(i).ContainsCompletely(r) = True Then
Debug.Print("KKKKKKKKKKKKKKK " + i.ToString)
del = i
End If
Next
e.Graphics.DrawRectangle(Pens.Cyan, r)
End If
For i As Integer = 0 To m_Lines.Count - 1
Me.m_Lines(i).Draw(e.Graphics, r)
Next
End Sub
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Bt_Select.Click
drawrec = True
End Sub
End Class
Public Class line
Public StartPoint As Point
Public EndPoint As Point
Public Filled As Boolean
Public ShapeColor As Color
Public PenWidth As Integer
Private m_selected As Boolean
Public Property Selected() As Boolean
Get
Return m_selected
End Get
Set(ByVal value As Boolean)
m_selected = value
End Set
End Property
Public Sub Draw(ByVal g As Graphics, ByVal r As Rectangle)
g.SmoothingMode = SmoothingMode.AntiAlias
If Me.ContainsCompletely(r) OrElse Me.Selected Then
Me.Selected = True
g.DrawLine(Pens.Red, Me.StartPoint, Me.EndPoint)
Else
g.DrawLine(Pens.Blue, Me.StartPoint, Me.EndPoint)
End If
End Sub
Public Function ContainsCompletely(ByVal r As Rectangle) As Boolean
If r.Contains(Me.StartPoint) AndAlso r.Contains(Me.EndPoint) Then
Return True
End If
Return False
End Function
End Class