【问题标题】:Drag and Drop images between numerous picture boxes在众多图片框之间拖放图像
【发布时间】:2022-04-12 08:01:21
【问题描述】:

我正在处理一个包含十个图片框的表单。孩子们应该能够将图片从一个图片框拖到其他任何一个图片框中。我阅读了一篇出色的 Microsoft 文章,其中解释了在两个图片框之间设置拖放的步骤。有五个子例程可以将一种方式拖放到第二个图片框中。

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

有没有更优雅的方法来做到这一点?我在下面放置了代码,用于在两个图片框之间进行拖放。我正在使用 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

【问题讨论】:

    标签: vb.net visual-studio-2010 drag-and-drop


    【解决方案1】:

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

    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
    

    来自cmets:

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

    当然是;而且很容易。将下面的代码更改为 DragDrop(),Move 的默认行为将是交换两个图像。如果他们按住 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
    

    来自cmets:

    如何将一个特定的图片框排除在“可拖动”之外?

    在 Load() 事件中,您将检查要在循环中排除的 PB。例如,这将排除“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
    

    【讨论】:

    • 谢谢!这看起来正是我正在寻找的优雅解决方案。我在实现您的代码时遇到了一个问题。我收到“AddHandler PB.DragDrop,AddressOf PBs__DragDrop”行的错误消息它说“PBs_DragDrop 未声明。由于其保护级别,它可能不可用。”我正在使用 Visual Basic Express 2010。
    • 表示找不到名为“PBs_DragDrop”的方法。您需要添加它。这是我上面代码示例中的 last 方法。 *或者你已经有了它,但名称与方法声明或 AddHandler 行中可能的拼写略有不同。
    • 搞定了。再次感谢分享代码。这就是我一直在寻找的解决方案!
    • 使用 AddHandlers,是否可以通过一次拖放“交换”两张图片? (即,将picturebox1 图像拖到picturebox3 图像上,然后立即让picturebox3 图像显示在picturebox1 中?我知道这超出了我原来问题的范围。
    • 你太棒了!谢谢!!
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-20
      • 2020-01-15
      • 1970-01-01
      • 2013-11-05
      • 1970-01-01
      • 1970-01-01
      • 2013-10-25
      • 1970-01-01
      相关资源
      最近更新 更多