在多个图片框之间拖放图像 [英] Drag and Drop images between numerous picture boxes

查看:166
本文介绍了在多个图片框之间拖放图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作一张有十张图片框的表单。孩子们应该可以将图片从一个画框拖到其他任何一个。我阅读了一篇优秀的Microsoft文章,解释了在两个图片框之间设置拖放的步骤。有五个子例程将一个方法拖放到第二个图片框中。



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



有没有更优雅的方式来做到这一点?我把下面的代码放在两个图片框之间进行拖放。我使用的是Visual Basic 2010 Express。谢谢。

 '启用删除。 
Private Sub Form1_Load(ByVal sender As System.Object,ByVal e As _
System.EventArgs)处理MyBase.Load
PictureBox2.AllowDrop = True
End Sub
'设置一个标志来显示PictureBox1的鼠标是否关闭
Private Sub PictureBox1_MouseDown(ByVal sender As Object,ByVal e As _
System.Windows.Forms.MouseEventArgs)Handles PictureBox1.MouseDown
如果不是PictureBox1.Image没有,然后
MouseIsDown = True
结束If
End Sub
'启动拖动并允许复制或移动PictureBox1
Private Sub PictureBox1_MouseMove ByVal sender As Object,ByVal e As _
System.Windows.Forms.MouseEventArgs)Handles PictureBox1.MouseMove
如果MouseIsDown然后
PictureBox1.DoDragDrop(PictureBox1.Image,DragDropEffects.Copy或_
DragDropEffects.Move)
如果$ b $结束b MouseIsDown = False
End Sub
'从PictureBox1复制或移动数据
Private Sub PictureBox1_DragEnter(ByVal sender As Object,ByVal e As _
System.Windows.Forms.DragEventArgs) Handles PictureBox1.DragEnter
如果e.Data.GetDataPresent(DataFormats.Bitmap)然后
'检查CTRL键。
如果e.KeyState = 9然后
e.Effect = DragDropEffects.Copy
Else
e.Effect = DragDropEffects.Move
End If
Else
e.Effect = DragDropEffects.None
End If
End Sub
'将图像分配给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)
'如果没有按下CTRL键,请删除源图片。
如果不是e.KeyState = 8然后
PictureBox1.Image = Nothing
End If
End Sub


解决方案

您可以使用AddHandler将任意数量的PictureBoxes连接到相同的处理程序方法。这些处理程序中的sender参数将告诉您哪个PictureBox是事件的源。在下面的代码中注意,没有一个方法在它们的末尾具有句柄子句;在Form的Load()事件中,一切都被动态地连线。由Form直接包含的所有PictureBox都将被连线。在我的测试项目中,我将其中的十个表格放在表单上:

 公共类Form1 

私人来源As PictureBox = Nothing

Private Sub Form1_Load(ByVal sender As System.Object,ByVal e As System.EventArgs)处理MyBase.Load
对于每个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
下一个
End Sub

Private Sub PBs_MouseMove(ByVal sender As Object,ByVal e As System.Windows.Forms.MouseEventArgs)
Dim PB As PictureBox = DirectCast(sender,PictureBox)
如果不是IsNothing(PB.Image)AndAlso e.Button = Windows.Forms.MouseButtons.Left然后
源= PB
PB.DoDragDrop(PB.Image,DragDropEffects.Copy或DragDropEffects.Move)
End If
End Sub

私有子PBs_DragEnter(ByVal sender As Object,ByVal e As System。 Windows.Forms.DragEventArgs)
如果e.Data.GetDataPresent(DataFormats.Bitmap)然后
如果My.Computer.Keyboard.CtrlKeyDown然后
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)
如果e.Data.GetDataPresent(DataFormats.Bitmap)然后
如果My.Computer.Keyboard.CtrlKeyDown然后
e .Effect = DragDropEffects.Copy
Else
e.Effect = DragDropEffects.Move
End If
Else
e.Effect = Drag DropEffects.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)
如果e.Effect = DragDropEffects.Move然后
如果不是(PB是源)然后
Source.Image = Nothing
End If
End If
End Sub

结束类

从评论中:


使用AddHandlers,是否可能以一个
拖放方式交换两张照片?


而且很容易。随着下面的代码更改为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'存储当前图像
PB.Image = e。 Data.GetData(DataFormats.Bitmap)'将其更改为丢弃的图像
如果e.Effect = DragDropEffects.Move然后
如果不是(PB是源)然后
Source.Image = tmpImage'将存储的图像放在源图片框(swap)中
End If
End If
End Sub

从评论中:


我如何排除一个特定的图片框不被拖动?


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

  Private Sub Form1_Load(ByVal sender As System.Object,ByVal e As System。 EventArgs)处理MyBase.Load 
对于每个PB作为PictureBox在Me.Controls.OfType(Of PictureBox)()
如果不是(PB是PictureBox1)然后
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
下一个
End Sub


I'm working on a form that has ten picture boxes. Children should be able to drag a picture from one picture box to any of the others. I read an excellent Microsoft article that explained the steps in setting up a drag/drop between two picture boxes. There were five sub routines to drag and drop one way into a second picture box.

My concern is that if the form has ten picture boxes, and the user can drag/drop between any of the ten boxes, that is a lot of code and and a lot of sub routines.

Is there a more elegant way to do this? I've put the code below for utilizing drag/drop between two picture boxes. I'm using Visual Basic 2010 Express. Thanks.

' 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

解决方案

You can use AddHandler to wire up any number of PictureBoxes to the same handler methods. The "sender" parameter in those handlers will tell you which PictureBox is the source of the event. Note in the code below that none of the methods have the "Handles" clause at the ends of them; everything is being wired up dynamically in the Load() event of the Form. All PictureBoxes that are contained directly by the Form will be wired up. In my test project I placed ten of them on the Form:

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

From the comments:

Using the AddHandlers, is it possible to "swap" two pictures with one drag/drop?

It certainly is; and is quite easy. With the change in code below to DragDrop(), the default behavior for Move will be to Swap the two images. If they hold down Ctrl to Copy then it will overwrite without swapping:

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

From the comments:

How would I exclude one specific picturebox from being "draggable"?

In the Load() event, you'd check for the PB to exclude in the loop. For example, this would exclude "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

这篇关于在多个图片框之间拖放图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆