程序范例CH8_DemoForm012.vb示范如何在两个PictureBox控件间拖曳图片,其功能特性如下所示:
- 如图8.13所示,您可以使用拖放方式将左侧PictureBox控件中的图片移动至右侧的PictureBox控件中,反之亦然,即左右两个PictureBox控件都可以作为拖放源与置放目标。
- 值得一提的是,如果您持续按着CTRL键,则可以使用拖放方式将左侧PictureBox控件中的图片复制到右侧的PictureBox控件中(如图8.14所示),反之亦然,即左右两个PictureBox控件都可以作为拖放源与置放目标。
图8.13示范如何拖放图片
图8.14通过拖放操作来复制图片
程序范例CH8_DemoForm012.vb在拖放操作方面的程序代码如下所列:' 声明一个常量以便侦测在拖曳期间CTRL键是否被按下。Const CtrlMask As Byte=8
Private Sub CH4_DemoForm065_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs)Handles MyBase.Load
' 由于目前无法在设计工具中去设定PictureBox控件
' 的AllowDrop属性,所以必须通过程序代码来加以设定。
picLeft.AllowDrop=True
picRight.AllowDrop=True
End Sub
' 处理左右两个PictureBox控件的MouseDown事件。
' 当鼠标指针位于控件的范围内而且鼠标按键被按下时便会引发此事件。
Private Sub PictureBox_MouseDown(ByVal sender As System.Object, _
ByVal e As System.Windows.Forms.MouseEventArgs)_
Handles picLeft.MouseDown, picRight.MouseDown
If e.Button=Windows.Forms.MouseButtons.Left Then
Dim pic As PictureBox=CType(sender, PictureBox)
' 初始化拖放操作。
If pic.Image IsNot Nothing Then
pic.DoDragDrop(pic.Image, _
DragDropEffects.Move Or DragDropEffects.Copy)
End If
End If
End Sub
' 处理左右两个PictureBox控件的DragEnter事件。
' 当某一个对象被拖曳至控件的范围内时就会引发
' 该控件的DragEnter事件。
Private Sub PictureBox_DragEnter(ByVal sender As System.Object, _
ByVal e As System.Windows.Forms.DragEventArgs)_
Handles picLeft.DragEnter, picRight.DragEnter
' 检查被拖曳的数据的类型是否适用于目标控件。
' 如果不适用,则拒绝置放。
If (e.Data.GetDataPresent(DataFormats.Bitmap))Then
' 如果在拖曳期间按着CTRL键,则执行复制操作;
' 反之,则执行移动操作。
If(e.KeyState And CtrlMask)=CtrlMask Then
e.Effect=DragDropEffects.Copy
Else
e.Effect=DragDropEffects.Move
End If
Else
e.Effect=DragDropEffects.None
End If
End Sub
' 处理左右两个PictureBox控件的DragDrop事件。
' 其实只要转换发送者(sender)然后检查Name属性
' 以便确认哪一个PictureBox控件要移除图像,就
' 可以使用同一个事件处理函数来处理两个PictureBox
' 控件的DragDrop事件。
Private Sub PictureBox_DragDrop(ByVal sender As System.Object, _
ByVal e As System.Windows.Forms.DragEventArgs)_
Handles picLeft.DragDrop, picRight.DragDrop
Dim pic As PictureBox=CType(sender, PictureBox)
pic.Image=_
CType(e.Data.GetData(DataFormats.Bitmap), Bitmap)
' 如果CTRL键没有被按下的话,就使另外一个PictureBox
' 控件(也就是在DragDrop事件中并不是sender的那一
' 个PictureBox控件)中的图像被移除。
If(e.KeyState And CtrlMask)<> CtrlMask Then
If pic.Name="picLeft" Then
picRight.Image=Nothing
Else
picLeft.Image=Nothing
End If
End If
End Sub
前面这两个关于文字与图片的拖放操作范例都是在同一个窗体上的两个控件间进行,其实它们也可在同一个应用程序内之不同窗体上的控件间拖放。下一个程序范例将示范如何接受从另外一个应用程序拖放而来的项目,在此一程序范例中,将接受从Windows资源管理器拖放而来的文件。
拖放文件在Windows资源管理器中使用拖放操作来移动或复制文件是大家所惯用的方式。Windows资源管理器充分支持拖放操作,而且这也是非常多用户所偏爱的文件使用方式。此外,许多用户非常习惯直接从Windows资源管理器将文件拖放至对应的应用程序中来打开它们。例如,从Windows资源管理器将一个 .doc 文件拖放至Microsoft Word即会将该文件打开在Microsoft Word中。
图8.15所示是程序范例CH8_DemoForm013.vb的运行界面。显而易见地,您可以从Windows资源管理器将一个或多个文件拖放至窗体上的ListBox控件中,而被拖放的文件的文件名称会被添加到ListBox控件中。以下是CH8_DemoForm013.vb的程序代码内容:
图8.15示范如何拖放文件
Private Sub ListBox1_DragEnter(ByVal sender As Object, _
ByVal e As System.Windows.Forms.DragEventArgs)_
Handles ListBox1.DragEnter
If e.Data.GetDataPresent(DataFormats.FileDrop)Then
e.Effect=DragDropEffects.All
End If
End Sub
Private Sub ListBox1_DragDrop(ByVal sender As Object, _
ByVal e As System.Windows.Forms.DragEventArgs)_
Handles ListBox1.DragDrop
If e.Data.GetDataPresent(DataFormats.FileDrop) Then
Dim MyFiles()As String
Dim i As Integer
' 将文件赋值给一个数组。
MyFiles=_
CType(e.Data.GetData(DataFormats.FileDrop), String())
' 循环处理数组并将文件添加到列表中。
For i=0 To MyFiles.Length-1
ListBox1.Items.Add(MyFiles(i))
Next
End If
End Sub
请注意这里在ListBox控件的DragEnter事件处理函数中将Effect属性设定成DragDropEffects.All。由于文件本身实际上并没有被移动或复制,因此拖放源如何设定AllowedEffects将无关紧要,设定All表示对任何的FileDrop都会启用置放。
就本范例而言,DataFormats.FileDrop格式会含有每一个被置放的文件的完整路径。本范例的操作逻辑是将所有被拖放的文件的完整路径填入ListBox控件中,当然,您可以采用其他作法。例如,您可以将被拖放的文件打开在一个MDI(多重文件界面)文件窗口中。