在众多图片框之间拖放图像

问题描述 投票:0回答:3

我正在制作一个有十个图片框的表单。孩子们应该能够将图片从一个图片框拖动到任何其他图片框。我阅读了一篇出色的 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
3个回答
3
投票

您可以使用 AddHandler 将任意数量的 PictureBox 连接到相同的处理程序方法。这些处理程序中的“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

来自评论:

使用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

来自评论:

我如何排除一个特定的图片框“可拖动”?

在 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

0
投票

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


0
投票

非常感谢。这也对我有帮助。也开始使用 vb.net 并且不熟悉所有的可能性。

我有两个 FlowLayoutPanel。源 FLP (flpSource) 包含 PictureBox 中的图像,这些图像由 OpenDialogue 根据用户输入动态填充。现在,如果用户想在另一个 FLP(flpSchedule)中使用这些图像,他必须使用鼠标左键单击并将其拖动并复制到 flpSchedule。

我尝试了 ChatGPT 建议的许多代码选项,但在选择图片框并拖动它时无法使代码工作。

你能帮忙吗?

© www.soinside.com 2019 - 2024. All rights reserved.