[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Drag'n'drop code - Similar to card game

Posted on 2005-04-29
6
Medium Priority
?
369 Views
Last Modified: 2008-02-01
Hi i'm trying to assemble a program and i've come across a need for the code similar to in the card game Solitaire for instance.. I need to be able to drag and drop an object (preferably with a picture) to a destination and be able to pull it off the object again.  I'm not quite so sure where to start, any ideas?
0
Comment
Question by:mortar
  • 3
  • 2
5 Comments
 
LVL 86

Accepted Solution

by:
Mike Tomlinson earned 1600 total points
ID: 13899254
There are several differents ways to go about "drag and drop" operations.

(1) A traditional drag and drop does not actually move the object while you are dragging...but instead leaves it in place.  The cursor changes to show where a drop can or cannot occur.  Here is an example of this kind of drag and drop:
http://www.experts-exchange.com/Programming/Programming_Languages/Dot_Net/VB_DOT_NET/Q_21328345.html#13411251
It is possible to define custom cursors instead of using the standard move, copy, no drop, etc...

(2) The drag and drop in most solitare games usually involves actually moving the source control as you drag it.  Then when it is dropped, you check its coordinates against those of the valid drop areas and see if it should be dropped or "snapped" to one those locations.  There are soooooooooo many ways to go about this...

Below is an example of one way to do it.  In the app there are six pictureboxes...three across the top and three across the bottom.  Double click each of the three top boxes and select an image for it.  Then drag each of those boxes in turn onto one of the bottom three boxes.  They should snap down onto them.  If more than one box is a candidate, the one with the largest area covered by the source picturebox will be selected.  You can pull the pictureboxes off again by dragging them back into the open space at the top of the form.  If one of the bottom target pictureboxes already has a picture on it then it no longer becomes a valid drop location until it is emptied again:

Public Class Form1
    Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

    Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() call

    End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    Friend WithEvents PictureBox1 As System.Windows.Forms.PictureBox
    Friend WithEvents PictureBox2 As System.Windows.Forms.PictureBox
    Friend WithEvents PictureBox3 As System.Windows.Forms.PictureBox
    Friend WithEvents PictureBox4 As System.Windows.Forms.PictureBox
    Friend WithEvents PictureBox5 As System.Windows.Forms.PictureBox
    Friend WithEvents PictureBox6 As System.Windows.Forms.PictureBox
    Friend WithEvents OpenFileDialog1 As System.Windows.Forms.OpenFileDialog
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.PictureBox1 = New System.Windows.Forms.PictureBox
        Me.PictureBox2 = New System.Windows.Forms.PictureBox
        Me.PictureBox3 = New System.Windows.Forms.PictureBox
        Me.PictureBox4 = New System.Windows.Forms.PictureBox
        Me.PictureBox5 = New System.Windows.Forms.PictureBox
        Me.PictureBox6 = New System.Windows.Forms.PictureBox
        Me.OpenFileDialog1 = New System.Windows.Forms.OpenFileDialog
        Me.SuspendLayout()
        '
        'PictureBox1
        '
        Me.PictureBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
        Me.PictureBox1.Location = New System.Drawing.Point(16, 8)
        Me.PictureBox1.Name = "PictureBox1"
        Me.PictureBox1.Size = New System.Drawing.Size(120, 120)
        Me.PictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage
        Me.PictureBox1.TabIndex = 0
        Me.PictureBox1.TabStop = False
        '
        'PictureBox2
        '
        Me.PictureBox2.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
        Me.PictureBox2.Location = New System.Drawing.Point(192, 8)
        Me.PictureBox2.Name = "PictureBox2"
        Me.PictureBox2.Size = New System.Drawing.Size(120, 120)
        Me.PictureBox2.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage
        Me.PictureBox2.TabIndex = 1
        Me.PictureBox2.TabStop = False
        '
        'PictureBox3
        '
        Me.PictureBox3.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
        Me.PictureBox3.Location = New System.Drawing.Point(368, 8)
        Me.PictureBox3.Name = "PictureBox3"
        Me.PictureBox3.Size = New System.Drawing.Size(120, 120)
        Me.PictureBox3.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage
        Me.PictureBox3.TabIndex = 2
        Me.PictureBox3.TabStop = False
        '
        'PictureBox4
        '
        Me.PictureBox4.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
        Me.PictureBox4.Location = New System.Drawing.Point(16, 240)
        Me.PictureBox4.Name = "PictureBox4"
        Me.PictureBox4.Size = New System.Drawing.Size(120, 120)
        Me.PictureBox4.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage
        Me.PictureBox4.TabIndex = 3
        Me.PictureBox4.TabStop = False
        '
        'PictureBox5
        '
        Me.PictureBox5.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
        Me.PictureBox5.Location = New System.Drawing.Point(192, 240)
        Me.PictureBox5.Name = "PictureBox5"
        Me.PictureBox5.Size = New System.Drawing.Size(120, 120)
        Me.PictureBox5.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage
        Me.PictureBox5.TabIndex = 4
        Me.PictureBox5.TabStop = False
        '
        'PictureBox6
        '
        Me.PictureBox6.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
        Me.PictureBox6.Location = New System.Drawing.Point(368, 240)
        Me.PictureBox6.Name = "PictureBox6"
        Me.PictureBox6.Size = New System.Drawing.Size(120, 120)
        Me.PictureBox6.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage
        Me.PictureBox6.TabIndex = 5
        Me.PictureBox6.TabStop = False
        '
        'Form1
        '
        Me.AllowDrop = True
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(506, 376)
        Me.Controls.Add(Me.PictureBox6)
        Me.Controls.Add(Me.PictureBox5)
        Me.Controls.Add(Me.PictureBox4)
        Me.Controls.Add(Me.PictureBox3)
        Me.Controls.Add(Me.PictureBox2)
        Me.Controls.Add(Me.PictureBox1)
        Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog
        Me.MaximizeBox = False
        Me.MinimizeBox = False
        Me.Name = "Form1"
        Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen
        Me.Text = "PictureBox Drag & Drop"
        Me.ResumeLayout(False)

    End Sub

#End Region

    Private startX As Single
    Private startY As Single
    Private sourcePBs As New ArrayList
    Private targetPBs As New ArrayList

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        sourcePBs.Add(Me.PictureBox1)
        sourcePBs.Add(Me.PictureBox2)
        sourcePBs.Add(Me.PictureBox3)
        targetPBs.Add(Me.PictureBox4)
        targetPBs.Add(Me.PictureBox5)
        targetPBs.Add(Me.PictureBox6)

        Dim pb As PictureBox

        For Each pb In sourcePBs
            AddHandler pb.DoubleClick, AddressOf Me.PictureBox_DoubleClick
            AddHandler pb.MouseDown, AddressOf Me.PictureBox_MouseDown
            AddHandler pb.MouseMove, AddressOf Me.PictureBox_MouseMove
            AddHandler pb.MouseUp, AddressOf Me.PictureBox_MouseUp
        Next
    End Sub

    Private Sub PictureBox_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs)
        If OpenFileDialog1.ShowDialog = DialogResult.OK Then
            Try
                sender.Image = Image.FromFile(OpenFileDialog1.FileName)
            Catch ex As Exception
            End Try
        End If
    End Sub

    Private Sub PictureBox_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        If e.Button = MouseButtons.Left Then
            startX = e.X
            startY = e.Y
            sender.BringToFront()
        End If
    End Sub

    Private Sub PictureBox_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        If e.Button = MouseButtons.Left Then
            sender.Location = New Point(sender.Location.X + e.X - startX, sender.Location.Y + e.Y - startY)
            If Not (sender.tag Is Nothing) Then
                Dim pb As PictureBox = CType(sender.tag, PictureBox)
                pb.Tag = Nothing
                sender.tag = Nothing
                pb.Visible = True
                pb.SendToBack()
            End If
        End If
    End Sub

    Private Sub PictureBox_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        Dim r1 As Rectangle = New Rectangle(sender.location, sender.size)
        Dim pb As PictureBox
        Dim r2 As Rectangle
        Dim r3 As Rectangle
        Dim area As Integer
        Dim largestArea As Integer = -1
        Dim selectedPB As PictureBox = Nothing

        For Each pb In targetPBs
            If pb.Tag Is Nothing Then
                r2 = New Rectangle(pb.Location, pb.Size)
                If r1.IntersectsWith(r2) Then
                    r3 = Rectangle.Intersect(r1, r2)
                    area = r3.Width * r3.Height
                    If area > largestArea Then
                        largestArea = area
                        selectedPB = pb
                    End If
                End If
            End If
        Next

        If Not (selectedPB Is Nothing) Then
            sender.location = selectedPB.Location
            sender.tag = selectedPB
            selectedPB.Tag = sender
            selectedPB.Visible = False
        End If
    End Sub

End Class
0
 
LVL 4

Author Comment

by:mortar
ID: 13899784
Very awesome code.  I had a quick look into the first one but preferred the code you posted here as I wanted the 'picture drag' as well, not just the boxed outline.  I added pictures in and it does exactly what I need although the double click function didn't work properly for me, I had to add the pictures in design mode?

I'm still getting used to the new version of VB.Net as I was using VB6 before, they've changed the shortcut key to the step-into function from F8 to F11, and the feature itself also doesn't seem to function the way i'm used to..  i.e. in VB6 if you stepped through your code then hovered over a 'mouse over' event, it would pause and drop back into the code design window to show you what event/code has taken place.  Although if I step into the code in this project, nothing happens when I double click the above picture boxes or drag them around the form to tell me what code is being processed in the background..

Ultimately I want to be able to tell which picture has been put in which box.. I've also noticed you can't drop more then one picture on a box at any one time which is perfect for what I want although I noticed although additional pictures cannot be 'snapped' as such they can be placed anywhere on or around the form, getting in the way of the other pictures.

Point increased to 400 ;)
0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 13899881
That's weird about the double clicking not working for you.  Did you create a completely new project and add ALL of the code I posted over the default code for the form?

You can determine which picture was put into which box by using the tag property of the pbs in the targetPBs arraylist.  If a picture is currently positioned on a target pb then that pbs tag property will have a reference to the corresponding picture...otherwise it will have Nothing to indicate it is empty.

As a side note, you can place ANYTHING in the tag property so you could create a more complex class to track more things at once and then place an instance of that class into the tag propety instead of a single reference to a pb.

It shouldn't be too difficult to make a snapping feature for the open area of the form.  Describe to me a little about you want it to work and perhaps I can give more suggestions or code.

~IM
0
 
LVL 4

Author Comment

by:mortar
ID: 13900018
Sorry my bad..

This message came up:
----------------
The project location is not fully trusted by the .NET runtime. This is usually because it is either a network share or pmapped to a network share not on the local machine. If the output path is under the project location, your code will not execute as fully trusted and you may receive unexpected security exceptions. Click OK to ignore and continue. Click CANCEL to choose a different project location.
----------------

It works ok if I save it on the local machine.  I'm running gentoo with an emulated Windows XP installation, so i'd prefer to save it to a 'network share' if possible.. Is there anyway to add it as a trusted location?
0
 
LVL 4

Author Comment

by:mortar
ID: 13900029
Ok basically the program that I want to create is the one described here but i've had more ideas since..

http://www.experts-exchange.com/Programming/Q_21356823.html

As described in the link, i'm trying to make a program to schedule game times for a volleyball centre and I was just trying to work out the easiest way to interface it..

From what you've given me here, I thought of making pictures of all the team names, and having them in a source pool, and being able to dragging 2 teams to a destination box (or 2 different boxes on the same court,time etc) to signify that they were playing each other.

0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Since .Net 2.0, Visual Basic has made it easy to create a splash screen and set it via the "Splash Screen" drop down in the Project Properties.  A splash screen set in this manner is automatically created, displayed and closed by the framework itsel…
Introduction When many people think of the WebBrowser (http://msdn.microsoft.com/en-us/library/2te2y1x6%28v=VS.85%29.aspx) control, they immediately think of a control which allows the viewing and navigation of web pages. While this is true, it's a…
this video summaries big data hadoop online training demo (http://onlineitguru.com/big-data-hadoop-online-training-placement.html) , and covers basics in big data hadoop .
Is your OST file inaccessible, Need to transfer OST file from one computer to another? Want to convert OST file to PST? If the answer to any of the above question is yes, then look no further. With the help of Stellar OST to PST Converter, you can e…
Suggested Courses
Course of the Month18 days, 17 hours left to enroll

834 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question