开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第31天,点击查看活动详情
拖放功能(两种方式)
Winform窗体中控件属性AllowDrop
表示允许拖放,通过启用它,可以实现将文件或数据直接拖入到窗体(控件)的功能。
DragDrop
事件则用来处理拖入的数据。
但是,仅设置AllowDrop = true
并不会触发DragDrop
事件,DragEnter
是会触发的。
要想触发DragDrop
事件,需要在DragEnter
事件方法中设置DragEventArgs
参数的Effect
属性,e.Effect
表示拖放操作中目标放置的效果。e.Effect
默认值为DragDropEffects.None
,没有任何拖入放置的效果,控件不接受拖入的对象,则DragDrop
无法触发。
e.Effect
仅表示放入的效果,无效果不接受拖放;其他任何取值仅表示显示的光标效果,不影响拖放和获取数据。如果对拖动操作使用自定义的光标效果,请参阅 GiveFeedbackEventArgs.UseDefaultCursors。
因此,WInform实现拖放功能的设置如下:
-
一
-
AllowDrop = true
:允许拖放 -
DragEnter
事件中设置e.Effect
为非None,接受拖入的对象 -
DragDrop
事件中处理拖入的数据及操作
因此,可以看到直接在DragEnter
处理拖放也是一样的。
AllowDrop = true
:允许拖放DragEnter
事件中处理拖入的数据及操作(设置e.Effect
为非必须)
Winform窗体启用拖拽后,拖放到窗体内的控件上一样有效。
除了上面两个事件,还有DragOver、DragLeave,以及QueryContinueDrag
(在拖放期间放生,允许拖动源是否取消拖放操作)。
获取拖入文件或文件夹的路径
使用DragDrop
AllowDrop = true;
DragEnter += Form1_DragEnter;
DragDrop += Form1_DragDrop;
在DragEnter
事件中使用e.Data.GetDataPresent
判断拖入的数据格式。如下,判断是文件拖放,则设置DragDropEffects
效果。
private void Form1_DragEnter(object sender, DragEventArgs e)
{
// 判断拖拽的数据格式
if (e.Data.GetDataPresent(DataFormats.FileDrop))
e.Effect = DragDropEffects.Link;
else
e.Effect = DragDropEffects.None;
}
private void Form1_DragDrop(object sender, DragEventArgs e)
{
string path = ((Array)e.Data.GetData(DataFormats.FileDrop)).GetValue(0).ToString();
InitialFileOrDir(path); // 处理文件
}
仅使用DragEnter
AllowDrop = true;
DragEnter += Form1_DragEnter;
// ............
private void Form1_DragEnter(object sender, DragEventArgs e)
{
// 判断拖拽的数据格式
if (e.Data.GetDataPresent(DataFormats.FileDrop)) {
e.Effect = DragDropEffects.Link;
string path = ((Array)e.Data.GetData(DataFormats.FileDrop)).GetValue(0).ToString();
// 处理文件或文件夹path...
}
else
e.Effect = DragDropEffects.None;
}
获取拖入的多个文件
private void Form1_DragEnter(object sender, DragEventArgs e)
{
// 判断拖拽的数据格式
if (e.Data.GetDataPresent(DataFormats.FileDrop)) // 处理文件拖放
{
e.Effect = DragDropEffects.Link;
// 多个文件
var files = (string[])e.Data.GetData(DataFormats.FileDrop);
}
else
e.Effect = DragDropEffects.None;
}
管理员权限运行时拖放文件无效的问题
从Windows Vista开始,由于用户界面权限隔离(User Interface Privilege Isolation
),所以无法从一个低权限运行的程序拖放到高权限运行的程序中。
因此,如果程序以管理员权限运行,要想实现拖放,文件资源管理器也应该以管理员权限打开(事实是,Windows Explorer文件资源管理器无法提升权限)。
以管理员权限打开程序,可以Debug或者直接运行,会发现拖放无效,不起作用。
解决办法有两种:
- 禁用UAC,不使用管理员权限运行
- 使用另外的文件管理器,以管理员权限打开。然后使用其进行拖拽
以管理员权限打开(文件)资源管理器的方法(不一定有效)
以管理员权限打开PowerShell,输入:
taskkill /f /im explorer.exe start-process explorer.exe
或,以管理员权限打开cmd,输入:
taskkill /f /im explorer.exe start explorer.exe
另,似乎 在资源管理器的选项中,设置 Launch folder windows in a separate process,然后关闭所有的文件夹后,再次打开也可以管理员权限(也似乎不一定起作用,应该和Windows版本有关)