Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations dencom on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Drag and Drop Image 1

Status
Not open for further replies.

furjaw

Programmer
Mar 27, 2006
49
US
Visual Basic 2005 Professional Edition:

I need to drag and drop an image from one PictureBox to another PictureBox where:

1) the image is visible while being dragged
2) the image can be dropped at any location within the target PictureBox
3) the image can be rotated within the target PictureBox




 
OK...what part are you stuck on? Also, show us what you've done so far. Keep in mind we're here to help with problems, not write an application for you free of charge.
 
The following copies an image from 1 PictureBox to another, but:
1) the image is not visible while being dragged
2) the image cannot be dropped at any location within the target PictureBox
3) the image cannot be rotated within the target PictureBox

Public Class Form1
Dim m_MouseIsDown As Boolean = False
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles MyBase.Load
' Enable dropping.
PictureBox2.AllowDrop = True
End Sub

Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As _
System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
If Not PictureBox1.Image Is Nothing Then
' Set a flag to show that the mouse is down.
m_MouseIsDown = True
End If
End Sub

Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As _
System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
If m_MouseIsDown Then
' Initiate dragging and allow either copy or move.
PictureBox1.DoDragDrop(PictureBox1.Image, DragDropEffects.Copy Or _
DragDropEffects.Move)
End If
m_MouseIsDown = False
End Sub

Private Sub PictureBox2_DragEnter(ByVal sender As Object, ByVal e As _
System.Windows.Forms.DragEventArgs) Handles PictureBox2.DragEnter
'If e.Data.GetDataPresent(DataFormats.Bitmap) Then
' ' Check for the CTRL key.
' If e.KeyState = 9 Then
e.Effect = DragDropEffects.Copy
'e.Effect = DragDropEffects.Scroll
' Else
'e.Effect = DragDropEffects.Move
' End If
'Else
' e.Effect = DragDropEffects.None
'End If
End Sub

Private Sub PictureBox2_DragDrop(ByVal sender As Object, ByVal e As _
System.Windows.Forms.DragEventArgs) Handles PictureBox2.DragDrop
' Assign the image to the PictureBox.
PictureBox2.Image = e.Data.GetData(DataFormats.Bitmap)
' If the CTRL key is not pressed, delete the source picture.
'If Not e.KeyState = 8 Then
' PictureBox1.Image = Nothing
'End If
End Sub

End Class
 
This demonstrates one way to show the image while you are dragging it. I've only partially written the function CanDrop so that you can see what needs to be done. As far as rotation is concerned, I wasn't aware that a PictureBox image could be rotated.

Code:
	Private Dragging As Boolean = False
	Private PictureBox3 As PictureBox = Nothing

	Private Function CanDrop() As Boolean

		Dim ok As Boolean = False
		'This only handles Top/Left of PictureBox3 but should give an idea of what needs to be done
		If (PictureBox3.Left >= PictureBox2.Left And PictureBox3.Left <= PictureBox2.Right) AndAlso _
		 (PictureBox3.Top >= PictureBox2.Top And PictureBox3.Top <= PictureBox2.Bottom) Then
			ok = True
		End If
		Return ok

	End Function

	Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As _
	System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown

		Dragging = True
		PictureBox3 = New PictureBox
		PictureBox3.Size = PictureBox1.Size
		PictureBox3.Image = PictureBox1.Image
		PictureBox3.SizeMode = PictureBox1.SizeMode
		PictureBox3.Location = PictureBox1.Location
		Me.Controls.Add(PictureBox3)

	End Sub

	Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As _
	System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove

		Dim loc As Point
		loc.X = e.X
		loc.Y = e.Y
		If Dragging Then
			PictureBox3.Location = loc
			PictureBox3.BringToFront()
		End If

	End Sub

	Private Sub PictureBox1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp

		If Dragging Then
			Dragging = False
			If CanDrop() Then
				PictureBox2.Image = PictureBox1.Image
				PictureBox2.SizeMode = PictureBox1.SizeMode
			End If
		End If
		PictureBox3.SendToBack()
		PictureBox3.Image = Nothing
		PictureBox3 = Nothing

	End Sub

	Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

		PictureBox2.Image = Nothing

	End Sub


By the way, Button1 is just so that you can clear PictureBox2 while testing.


Hope this helps.

[vampire][bat]
 
I am getting the following error on this line: PictureBox3.Location = loc

Structure 'System.Drawing.Point' cannot be indexed because it has no default property.


 
Two things, firstly rotating your image can be done as follows:


Code:
	Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click

		Dim i As Image
		If Not PictureBox2.Image Is Nothing Then
			i = PictureBox2.Image
			i.RotateFlip(CType(RotateFlip, RotateFlipType))
			PictureBox2.Image = i
			i = Nothing
			'MessageBox.Show(RotateFlip.ToString + ", " + CType(RotateFlip, RotateFlipType).ToString)
			RotateFlip = (RotateFlip + 1) Mod 8
		End If

	End Sub

Secondly: I don't understand your error message if you copied and pasted my sample. There is no indexing.

.Location is System.Drawing.Point

and

Dim loc As Point
loc.X = e.X
loc.Y = e.Y

sets up a Point variable which can be directly assigned to .Location


Hope this helps.


[vampire][bat]
 
Sorry, I forgot to include the following in the declarations section:

Private Dragging As Boolean = False
Private PictureBox3 As PictureBox = Nothing
Private RotateFlip As Integer = 0


[vampire][bat]
 
A couple of minor changes:

Code:
Public Class Form1

	Private Dragging As Boolean = False
	Private DragCopy As Boolean = False
	Private PictureBox3 As PictureBox = Nothing
	Private RotateFlip As Integer = 0
	Private PictureBox1Image As Image	'to save image during testing

	Private Function CanDrop() As Boolean

		'Not needed but saves a lot of typing and makes the boolean expression easier to read
		Dim pb2left As Integer = PictureBox2.Left
		Dim pb2top As Integer = PictureBox2.Top
		Dim pb2right As Integer = PictureBox2.Right
		Dim pb2bottom As Integer = PictureBox2.Bottom
		Dim pb3left As Integer = PictureBox3.Left
		Dim pb3top As Integer = PictureBox3.Top
		Dim pb3right As Integer = PictureBox3.Right
		Dim pb3bottom As Integer = PictureBox3.Bottom

		'IF any part of PictureBox3 is over PictureBox2 THEN return True ELSE return False
		Return _
		 ((pb3left >= pb2left And pb3left <= pb2right) OrElse _
			(pb3right >= pb2left And pb3right <= pb2right)) _
		 AndAlso _
		 ((pb3top >= pb2top And pb3top <= pb2bottom) OrElse _
			(pb3bottom >= pb2top And pb3bottom <= pb2bottom))

	End Function

	Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As _
	System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown

		If Not PictureBox1.Image Is Nothing Then
			Dragging = True
			With PictureBox1
				PictureBox3 = New PictureBox
				PictureBox3.Size = .Size
				PictureBox3.Image = .Image
				PictureBox3.SizeMode = .SizeMode
				PictureBox3.Location = .Location
			End With
			Me.Controls.Add(PictureBox3)
		End If

	End Sub

	Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As _
	System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove

		Dim loc As Point
		loc.X = e.X
		loc.Y = e.Y
		If Dragging Then
			PictureBox3.Location = loc
			PictureBox3.BringToFront()
		End If

	End Sub

	Private Sub PictureBox1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp

		If Dragging Then
			Dragging = False
			If CanDrop() Then
				PictureBox2.Image = PictureBox1.Image
				PictureBox2.SizeMode = PictureBox1.SizeMode
				If Not DragCopy Then PictureBox1.Image = Nothing
				DragCopy = False
			End If
			PictureBox3.SendToBack()
			PictureBox3.Image = Nothing
			PictureBox3 = Nothing
		End If

	End Sub

	Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

		PictureBox2.Image = Nothing
		PictureBox1.Image = PictureBox1Image

	End Sub

	Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click

		Dim i As Image
		If Not PictureBox2.Image Is Nothing Then
			i = PictureBox2.Image
			i.RotateFlip(CType(RotateFlip, RotateFlipType))
			PictureBox2.Image = i
			i = Nothing
			RotateFlip = (RotateFlip + 1) Mod 8
		End If

	End Sub

	Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown

		If Dragging Then
			DragCopy = e.Control
		End If

	End Sub

	Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

		PictureBox1Image = PictureBox1.Image
		Me.KeyPreview = True
		' *** Possibly use the following as a start point to offer the 
		' *** Rotation / Flip options on a right-click menu
		'For a As Integer = 0 To 7
		'	??? = CType(a, RotateFlipType).ToString()
		'Next

	End Sub
End Class

Hope this helps

[vampire][bat]
 
Hey man, you are GOOD!!!
My PictureBox1 is postage stamp size.
My PictureBox2 is large.
I want to be able to position the small PictureBox1 anywhere within PictureBox2.
 
Thank you.

As far as I am aware, a PictureBox can only contain one image (other than an ErrorImage) at a time and I don't think you can specify its position within the PictureBox.

What you might want to try is replacing your PictureBox2 with a Panel, and then, when "dropping", add a PictureBox to the Panel's Controls Collection. You can then set the Location of the new PictureBox, relative to the Panel.


Hope this helps.

[vampire][bat]
 
I found that if I click the right mouse button, I can copy the image anywhere within PictureBox2, and, I can copy multiple images. (I changed DragCopy to True). But, I can't rotate the ones that I placed with a right mouseclick. I can only rotate the one that I dragged and dropped which always went to the upper left corner no matter where I dropped it.

Also, I tried placing this command:
PictureBox3.BackColor=Color.Transparent
at various places, but, the background color never changed from beige.
 
If I rotate after dropping the image which always goes to the upper right corner, then drag again, I can place rotated images anywhere in PictureBox2 by clicking the right mouse button. (I changed DragCopy to true).
 
If I drag another rotated copy of the image over a previously placed copy, it will stay there without clicking the right mouse button.
 
Here is what I am trying to do:

PictureBox1.Image is an Orthodontic spring:

PictureBox2.BackgroundImage is upper and lower teeth:

The spring (PictureBox1.Image) can be placed on any tooth (PictureBox2.BackgroundImage).
It can be flipped to press against either the right or left side of a tooth.
Springs could be placed on more than one tooth.
The springs are anchored in acrylic and are used to move (straighten) teeth.

 
I heard that System.Drawing.Drawing2D.Matrix allows rotation in 1 degree increments - not that I know how to do it.
 
Sorry for the delay in replying - I wont have chance to look at this any further until the weekend.

If you still need assistance, if you post on Friday confirming the "current state of play", I will have another look over the weekend.

[vampire][bat]
 
jo0ls at xtremevbtalk.com wrote a program that does it all!

1) Transparent backround on dragged objects.
2) See object as it is being dragged.
3) Rotate object.
4) Nudge object.
5) Delete object.
6) Drag multiple objects.
7) Drag multiple copies of an object.
8) Redrag objects.
9) Drag objects of any size

Wow!

<
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top