How to remove a line which is drawn on a form - vb.net

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

Related

How can I dispose the image from the following code?

I am using VS 2019.
The presented code should display an animated GIF each time the 'btn_Display' is clicked.
If the image is disposed I've got an error at ImageAnimator.UpdateFrames() in PictureBox.Paint after the second click.
Public Class Form1
Dim animatedImage As Bitmap
Dim currentlyAnimating As Boolean = False
Dim framecounter As Integer
Dim framecount As Integer
Dim framdim As Imaging.FrameDimension
Dim gifFile As String
Private Sub OnFrameChanged(ByVal o As Object, ByVal e As EventArgs)
PictureBox1.Invalidate()
End Sub
Sub AnimateImage()
If Not currentlyAnimating Then
ImageAnimator.Animate(animatedImage, New EventHandler(AddressOf Me.OnFrameChanged))
currentlyAnimating = True
End If
End Sub
Private Sub PictureBox1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
If framecounter < framecount Then
AnimateImage()
ImageAnimator.UpdateFrames()
e.Graphics.DrawImage(Me.animatedImage, New Point(0, 0))
framecounter += 1
Application.DoEvents()
End If
End Sub
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
PictureBox1.SizeMode = PictureBoxSizeMode.AutoSize
PictureBox1.Visible = False
gifFile = "E:\1.gif"
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles btn_Display.Click
startGif(gifFile)
End Sub
Sub startGif(ByVal FlName As String)
currentlyAnimating = False
animatedImage = New Bitmap(FlName)
framecounter = 0
PictureBox1.Size = animatedImage.Size
PictureBox1.Visible = True
framdim = New Imaging.FrameDimension(animatedImage.FrameDimensionsList(0))
framecount = animatedImage.GetFrameCount(framdim)
WaitFor_eoAnimation()
animatedImage.Dispose() ' <-----
PictureBox1.Visible = False
End Sub
Private Sub WaitFor_eoAnimation()
' Wait for end of animation
Do
Application.DoEvents()
Loop While framecounter < framecount 'currentlyAnimating
End Sub
End Class
Thanks in advance ... Eitan

Error : reference to a non-shared member requires an object reference

The game i am making is connect 4 , the form I am calling from is here :
Public Class Form1
Public players(1) As IPlayer
Public playerturn As IPlayer
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
buttons()
init()
End Sub
Public Sub init()
playerturn = players(0)
Board1.Init()
currentaturn.Text = String.Format("{0}'s turn", playerturn.name)
End Sub
Sub buttons()
For i As Integer = 0 To 7
Dim btn As New Button()
btn.Text = "drop"
btn.BackColor = Color.Pink
btn.Size = New Size(40, 40)
btn.Location = New Point(i * 48, 0)
btn.Tag = i
AddHandler btn.Click, AddressOf clickbutton
Panel1.Controls.Add(btn)
Next
End Sub
Sub clickbutton(ByVal sender As Object, ByVal e As EventArgs)
Dim clickedbutton As Button = CType(sender, Button)
Dim clickedcolumn As Integer = clickedbutton.Tag
If (Board1.addpiecetocolumn(clickedcolumn, Color.Red) = False) Then
Else
End If
End Sub
Private Sub Panel1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Panel1.Paint
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles LDBTN.Click
End Sub
Private Sub Label2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles currentaturn.Click
End Sub
Private Sub RESETBTN_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RESETBTN.Click
loginsys.Show()
Me.close
End Sub
End Class
and the form I am calling to :
Public Class board
Public board(8, 8) As panelbox
Public columns As Integer = 7
Public rows As Integer = 7
Public Sub New()
InitializeComponent()
Init()
End Sub
Public Sub Init()
Me.Controls.Clear()
For i As Integer = 0 To columns - 1
For j As Integer = 0 To rows - 1
board(i, j) = New panelbox()
board(i, j).Size = New Size(50, 50)
board(i, j).Location = New Point((i * 45), (j * 45))
board(i, j).BackColor = Color.DodgerBlue
Me.Controls.Add(board(i, j))
Next
Next
End Sub
Public Function addpiecetocolumn(ByVal x As Integer, ByVal colo As Color) As Boolean
For y As Integer = rows - 1 To 0 Step -1
If (board(x, y).Used = False) Then
board(x, y).Used = True
board(x, y).BackColor = colo
Return True
End If
Next
Return False
End Function
End Class
it should be noted that I am naming the second form board and the part that's calling the error is from the first form :
Public Sub init()
playerturn = players(0)
Board1.Init()
currentaturn.Text = String.Format("{0}'s turn", playerturn.name)
End Sub
Any help would be great
Use Public Shared Function function_name, in this case, you have to call it like board.function_name

Smart Phone Like Scrolling Solution issue (vb.net)

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

Click and drag implementation on a rectangle VB.NET

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

Need to change a mouse event args with a checkbox

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