程序范例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的程序代碼內容:

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(多重文件界面)文件窗口中。

