在VB.NET中实现拖放操作 DragDrop

Vb.net 专栏收录该内容
92 篇文章 2 订阅
 
绪论
用户一般分为两类:一类习惯用键盘操作,一类习惯用鼠标操作。程序员们在编程时一般会提供快捷键或快捷方式来照顾到那些习惯键盘的用户,但是那些鼠标用户却被忽略了。因为程序员们一般都习惯用键盘,所以他们这种重视键盘操作的特点是可以理解的,但是每个程序员也应该考虑到提供鼠标支持。
鼠标用户所期望的一件事就是能够在应用程序中实现拖放。如果你注意到一些大型应用程序或windows自身的话,拖放操作几乎随处可见。例如,用户可能已经习惯了在windows资源管理器中拖放文件,或在中拖放文本等操作了。
尽管拖放操作随处可见,但是只有极少数程序员在他们所编写的程序中实现拖放功能,最可能的原因是他们认为实现拖放可能比想象的还要难。这篇文章列举了如何在窗体内、窗体之间,甚至应用程序之间移动文本、图片或者文件的例子,显示了在中实现拖放是非常容易得。
拖放如何进行
拖放实际上就如同用鼠标复制粘帖,因此你必须有一个可以复制或移动的源,也要有一个可以粘贴的目的地。在这两个操作过程中,数据是保存在内存中的。复制粘贴用的是剪切版,而拖放用的却是一种本质上是私有剪切板的Dataobject的对象。
下面是典型的托放操作的时间序列:
1、拖是通过调用源控件的DoDragDrop方法来初始化的,DoDragDrop有两个参数
data,指定将要传送的数据
allowedEffects,指定允许进行的操作(复制或移动)
这样自动创建了一个新的Dataobject对象
2、接下来就依次激发了GiveFeedBack事件。在大多数情况下,你并不需要担心GiveFeedBack事件,然而你如果想自定义拖放过程中的鼠标指针的话,你可以在这些地方加上你的代码。
3、任何有AllowDrop属性而且被设置成True的控件都是隐含的Drop对象。AllowDrop属性可以在设计时的属性窗口中进行设置,也可以在Form_load事件自动加载。
4、当鼠标移到某个控件时,就同时激发了这个控件的DragEnter事件。GetDataPresent方法是用来确认拖过来的数据是否适合目标控件,Effect属性是用来显示适当的鼠标指针。
5、如果用户在有效的目标控件上释放鼠标,就同时激发了DragDrop事件。DragDrop事件句柄中的代码从DataObject对象中释放数据并把它显示在目标控件中。
从VB6到VB.NET有何变化?
(略)
拖放文本
拖放操作的一个很简单然而很有用的情形是从一个TextBox控件复制文本到另一个TextBox控件。当然你可以只用键盘就能实现,然而拖放更简单因为它仅需要鼠标的移动就可以完成。
1、向一个窗体中添加两个文本框,并把第二个TextBox控件的AllowDrop属性设置成True,添加如下代码。
PrivateMouseIsDownAsBoolean=False
PrivateSubTextBox1_MouseDownHandlesTextBox1.MouseDown
‘Setaflagtoshowthatthemouseisdown.
MouseIsDown=True
EndSub

PrivateSubTextBox1_MouseMoveHandlesTextBox1.MouseMove
IfMouseIsDownThen
‘Initiatedragging.
TextBox1.DoDragDrop
EndIf
MouseIsDown=False
EndSub

PrivateSubTextBox2_DragEnterHandlesTextBox2.DragEnter
‘Checktheformatofthedatabeingdropped.
If)Then
‘Displaythecopycursor.
e.Effect=DragDropEffects.Copy
Else
‘Displaytheno-dropcursor.
e.Effect=DragDropEffects.None
EndIf
EndSub

PrivateSubTextBox2_DragDropHandlesTextBox2.DragDrop
‘Pastethetext.
TextBox2.Text=e.Data.GetDataHandlesMyBase.Load
‘Enabledropping.
PictureBox2.AllowDrop=True
EndSub

PrivateSubPictureBox1_MouseDownHandlesPictureBox1.MouseDown
IfNotPictureBox1.ImageIsNothingThen
‘Setaflagtoshowthatthemouseisdown.
m_MouseIsDown=True
EndIf
EndSub

PrivateSubPictureBox1_MouseMoveHandlesPictureBox1.MouseMove
Ifm_MouseIsDownThen
‘Initiatedraggingandalloweithercopyormove.
PictureBox1.DoDragDrop
EndIf
m_MouseIsDown=False
EndSub

PrivateSubPictureBox2_DragEnterHandlesPictureBox2.DragEnter
Ife.Data.GetDataPresentThen
‘CheckfortheCTRLkey.
Ife.KeyState=9Then
e.Effect=DragDropEffects.Copy
Else
e.Effect=DragDropEffects.Move
EndIf
Else
e.Effect=DragDropEffects.None
EndIf
EndSub

PrivateSubPictureBox2_DragDropHandlesPictureBox2.DragDrop
‘AssigntheimagetothePictureBox.
PictureBox2.Image=e.Data.GetData
‘IftheCTRLkeyisnotpressed,deletethesourcepicture.
IfNote.KeyState=8Then
PictureBox1.Image=Nothing
EndIf
EndSub
注意到上面的例子中第二个PictureBox控件的AllowDrop属性是在Form1_load事件中设置的,这是因为设计时PictureBox并没有AllowDrop属性。
在MouseDown事件中,代码首先检测是否有要赋给PictureBox的图片;如果没有的话,当你移动图片后,接下来的click将引发一个意外。
还应该注意到的是在DragEnter和DragDrop事件中代码检测CTRL键是否被按下,从而决定是否是复制还是移动图片。为什么值会不同呢?在DragEnter事件中,当鼠标左键按下时,产生的值是1,在加上CTRL的值8,从而值为9。见KeyState枚举列表DragEventArgs.KeyStateProperty。
到目前为止,这两个例子处理的都是同一窗体不同控件间的拖放,然而在同一应用程序的不同窗体上同样适用。
拖动文件
在windows中拖放通常是复制或移动文件,windows完全支持该功能,而且对许多用户来说这也是操作文件的优选方式。除此之外,用户已经习惯了把文件拖动到一个程序来打开文件的方式,像拖动一个doc文件到word来打开。
在这个例子中用从windows资源管理器拖来的文件来操作ListBox控件。
向窗体中添加一个ListBox控件,并设置其AllowDrop属性为True,并添加如下代码:

PrivateSubListBox1_DragEnterHandlesListBox1.DragEnter
Ife.Data.GetDataPresentThen
e.Effect=DragDropEffects.All
EndIf
EndSub

PrivateSubListBox1_DragDropHandlesListBox1.DragDrop
Ife.Data.GetDataPresentThen
DimMyFilesAsString
DimiAsInteger

‘Assignthefilestoanarray.
MyFiles=e.Data.GetData
‘Loopthroughthearrayandaddthefilestothelist.
Fori=0ToMyFiles.Length-1
ListBox1.Items.Add)
Next
EndIf
EndSub
你可能已经注意到了DragEnter事件中的Effect属性被设置成DragDropEffects.All。因为文件本身并不是真的就被复制或移动了,因此源控件设置成哪个AllowedEffects并没有关系,所以指定All对任何FileDrop都可以。
在上面的例子中FileDrop格式包含了每个被拖动文件的全路径。
下面的例子讲述了拖放的一个特殊情况:在两个列表间来回拖放。
表间拖放
拖放的另一个情况是从一个列表移动项目到另一个列表。这种情况下拖放将变得更加简单。
向窗体中添加两个ListView控件,并把他们的AllowDrop、Multiselect、View属性分别设置成True、True、List。并添加如下代码:
PrivateSubListView_ItemDragHandlesListView1.ItemDrag,_
ListView2.ItemDrag
DimmyItemAsListViewItem
DimmyItemsAsListViewItem
DimiAsInteger=0

‘LoopthoughtheSelectedItemscollectionforthesource.
ForEachmyItemInsender.SelectedItems
‘AddtheListViewItemtothearrayofListViewItems.
myItems=myItem
i=i+1
Next
‘CreateaDataObjectcontaingthearrayofListViewItems.
sender.DoDragDrop,myItems),_
DragDropEffects.Move)
EndSub

PrivateSubListView_DragEnterHandlesListView1.DragEnter,_
ListView2.DragEnter
‘CheckforthecustomDataFormatListViewItemarray.
Ife.Data.GetDataPresent)Then
e.Effect=DragDropEffects.Move
Else
e.Effect=DragDropEffects.None
EndIf
EndSub

PrivateSubListView_DragDropHandlesListView1.DragDrop,_
ListView2.DragDrop
DimmyItemAsListViewItem
DimmyItemsAsListViewItem=_e.Data.GetData)
DimiAsInteger=0

ForEachmyItemInmyItems
‘Addtheitemtothetargetlist.
sender.Items.Add.Text)
‘Removetheitemfromthesourcelist.
IfsenderIsListView1Then
ListView2.Items.Remove)
Else
ListView1.Items.Remove)
EndIf
i=i+1
Next
EndSub
你可能不明白为什么这个例子中用的是ListView控件而不是ListBox控件,这个问题题的好,因为ListBox控件不支持多项拖放。
ListView和TreeView控件有个ItemDrag事件。上面的例子中,一个ItemDrag事件句柄覆盖了两个控件,并在列在Handles从句。Sender参数表明哪个控件正在初始化Drag。
因为DataFormats类没有ListViewItem类型成员,数据必须传递给一个系统类型。ItemDrag创建了一个ListViewItem类型的数组,并用一个循环来遍历SelectedItem集合。在DoDragDrop方法中,创建了一个新的DataObject并用数组来来对它进行操作。可以用这种方法来拖放任何系统类型。
结论:
正像你从这些例子中所看到的一样,为应用程序添加拖放操作并不是很难。当你理解了这些基本的技巧后,你就可以为你自己的程序添加拖放的代码了
  • 0
    点赞
  • 0
    评论
  • 2
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值