Vb.net 在多个图片框之间拖放图像

Vb.net 在多个图片框之间拖放图像,vb.net,visual-studio-2010,drag-and-drop,Vb.net,Visual Studio 2010,Drag And Drop,我正在制作一个有十个图片框的表单。孩子们应该能够将图片从一个图片框拖动到其他任何一个图片框。我读了一篇优秀的微软文章,解释了在两个图片框之间设置拖放的步骤。有五个子例程可以将一条路径拖放到第二个图片框中 我担心的是,如果表单有十个图片框,并且用户可以在这十个框中的任何一个框之间拖放,那么就需要大量的代码和大量的子例程 有没有更优雅的方法?下面是在两个图片框之间使用拖放的代码。我正在使用Visual Basic 2010 Express。谢谢 ' Enable dropping.

我正在制作一个有十个图片框的表单。孩子们应该能够将图片从一个图片框拖动到其他任何一个图片框。我读了一篇优秀的微软文章,解释了在两个图片框之间设置拖放的步骤。有五个子例程可以将一条路径拖放到第二个图片框中

我担心的是,如果表单有十个图片框,并且用户可以在这十个框中的任何一个框之间拖放,那么就需要大量的代码和大量的子例程

有没有更优雅的方法?下面是在两个图片框之间使用拖放的代码。我正在使用Visual Basic 2010 Express。谢谢

' Enable dropping.
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As  _
        System.EventArgs) Handles MyBase.Load
            PictureBox2.AllowDrop = True
        End Sub
' Set a flag to show that the mouse is down for PictureBox1
        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
                MouseIsDown = True
            End If
        End Sub
' Initiate dragging and allow either copy or move for PictureBox1
        Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As  _
        System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
            If MouseIsDown Then
                PictureBox1.DoDragDrop(PictureBox1.Image, DragDropEffects.Copy Or _
        DragDropEffects.Move)
            End If
            MouseIsDown = False
        End Sub
 'Copy or Move data from PictureBox1
        Private Sub PictureBox1_DragEnter(ByVal sender As Object, ByVal e As  _
        System.Windows.Forms.DragEventArgs) Handles PictureBox1.DragEnter
            If e.Data.GetDataPresent(DataFormats.Bitmap) Then
                ' Check for the CTRL key. 
                If e.KeyState = 9 Then
                e.Effect = DragDropEffects.Copy
                Else
                    e.Effect = DragDropEffects.Move
                End If
            Else
                e.Effect = DragDropEffects.None
            End If
         End Sub
 ' Assign the image to the PictureBox2
        Private Sub PictureBox2_DragDrop(ByVal sender As Object, ByVal e As  _
        System.Windows.Forms.DragEventArgs) Handles PictureBox2.DragDrop
            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

您可以使用AddHandler将任意数量的PictureBoxe连接到相同的处理程序方法。这些处理程序中的“sender”参数将告诉您哪个PictureBox是事件的源。请注意,在下面的代码中,没有一个方法的末尾有“Handles”子句;所有内容都在表单的Load()事件中动态连接。表单直接包含的所有PictureBox都将连接起来。在我的测试项目中,我将其中十个放在表格上:

Public Class Form1

    Private Source As PictureBox = Nothing

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        For Each PB As PictureBox In Me.Controls.OfType(Of PictureBox)()
            PB.AllowDrop = True
            AddHandler PB.MouseMove, AddressOf PBs_MouseMove
            AddHandler PB.DragEnter, AddressOf PBs_DragEnter
            AddHandler PB.DragDrop, AddressOf PBs_DragDrop
            AddHandler PB.DragOver, AddressOf PBs_DragOver
        Next
    End Sub

    Private Sub PBs_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        Dim PB As PictureBox = DirectCast(sender, PictureBox)
        If Not IsNothing(PB.Image) AndAlso e.Button = Windows.Forms.MouseButtons.Left Then
            Source = PB
            PB.DoDragDrop(PB.Image, DragDropEffects.Copy Or DragDropEffects.Move)
        End If
    End Sub

    Private Sub PBs_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs)
        If e.Data.GetDataPresent(DataFormats.Bitmap) Then
            If My.Computer.Keyboard.CtrlKeyDown Then
                e.Effect = DragDropEffects.Copy
            Else
                e.Effect = DragDropEffects.Move
            End If
        Else
            e.Effect = DragDropEffects.None
        End If
    End Sub

    Private Sub PBs_DragOver(sender As Object, e As DragEventArgs)
        If e.Data.GetDataPresent(DataFormats.Bitmap) Then
            If My.Computer.Keyboard.CtrlKeyDown Then
                e.Effect = DragDropEffects.Copy
            Else
                e.Effect = DragDropEffects.Move
            End If
        Else
            e.Effect = DragDropEffects.None
        End If
    End Sub

    Private Sub PBs_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs)
        Dim PB As PictureBox = DirectCast(sender, PictureBox)
        PB.Image = e.Data.GetData(DataFormats.Bitmap)
        If e.Effect = DragDropEffects.Move Then
            If Not (PB Is Source) Then
                Source.Image = Nothing
            End If
        End If
    End Sub

End Class
从评论中:


使用AddHandler,是否可以用一张图片“交换”两张图片 拖放

当然是,;而且很容易。将下面的代码更改为DragDrop(),移动的默认行为将是交换两个图像。如果按住Ctrl键进行复制,则会覆盖而不进行交换:

Private Sub PBs_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs)
    Dim PB As PictureBox = DirectCast(sender, PictureBox)
    Dim tmpImage As Image = PB.Image ' store the current image
    PB.Image = e.Data.GetData(DataFormats.Bitmap) ' change it to the dropped image
    If e.Effect = DragDropEffects.Move Then
        If Not (PB Is Source) Then
            Source.Image = tmpImage ' put the stored image in the source picturebox (swap)
        End If
    End If
End Sub
从评论中:

我如何将一个特定的picturebox排除在“可拖动”之外

在Load()事件中,检查循环中要排除的PB。例如,这将排除“PictureBox1”:


关于我最后一个关于排除某些pictureboxes的可拖动性的问题(见最后一条评论),我发现了pictureboxes的“enabled”属性。根据需要打开或关闭该属性非常容易。

谢谢!这看起来正是我想要的优雅解决方案。我在实现你的代码时遇到了一个问题。我收到一条关于“AddHandler PB.DragDrop,AddressOf PBs__DragDrop”的错误消息,它说“PBs_DragDrop未声明。它可能由于其保护级别而不可用。”我正在使用Visual Basic Express 2010。它说找不到名为“PBs_DragDrop”的方法。你需要添加它。这是上面代码示例中的最后一个方法*或者您已经有了它,但名称与方法声明或AddHandler行中可能的键入略有不同。让它工作了吗。再次感谢分享代码。这就是我一直在寻找的解决方案!使用AddHandler,是否可以通过一次拖放“交换”两张图片?(即,将picturebox1图像拖动到picturebox3图像,然后立即让picturebox3图像显示在picturebox1中?我知道这超出了我原来问题的范围。你太棒了!谢谢!!
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    For Each PB As PictureBox In Me.Controls.OfType(Of PictureBox)()
        If Not (PB Is PictureBox1) Then
            PB.AllowDrop = True
            AddHandler PB.MouseMove, AddressOf PBs_MouseMove
            AddHandler PB.DragEnter, AddressOf PBs_DragEnter
            AddHandler PB.DragDrop, AddressOf PBs_DragDrop
            AddHandler PB.DragOver, AddressOf PBs_DragOver
        End If
    Next
End Sub