Windows文件拖放操作优化

在Windows应用程序开发中,实现文件的拖放操作是一个常见的需求。特别是在处理来自外部设备或服务器的大文件时,传统的拖放方法可能会因为文件下载速度慢而导致操作被取消。本文将介绍一种优化方法,通过实现一个自定义的拖放助手类来提高操作的效率和用户体验。

作者开发了一个Windows应用程序,该程序可以在ListView中显示外部设备上的文件。需求是允许用户通过拖放操作将文件从设备移动到本地机器。最初,作者尝试在调用ListView_ItemDrag事件的DoDragDrop方法之前,下载所有选定的文件。这种方法对于一两个小文件是有效的,但对于更多或更大的文件则不适用。因为当用户按下鼠标键时,文件下载速度变慢,Windows可能会取消拖放操作。

使用代码

首先,需要创建一个名为FileDragDropHelper的类,该类继承自System.Windows.Forms.DataObject。接下来,需要重写GetDataPresent方法。在这个方法中,不要忘记调用基类的GetDataPresent方法。

public class FileDragDropHelper : DataObject { private int _downloadIndex; private readonly Action _downloadAction; public FileDragDropHelper(Action downloadAction) { if (downloadAction == null) throw new ArgumentNullException("downloadAction"); _downloadAction = downloadAction; } public override bool GetDataPresent(string format) { StringCollection fileDropList = GetFileDropList(); if (fileDropList.Count > _downloadIndex) { string fileName = Path.GetFileName(fileDropList[_downloadIndex]); if (!string.IsNullOrEmpty(fileName)) { _downloadAction(fileDropList[_downloadIndex]); _downloadIndex++; } } return base.GetDataPresent(format); } }

第三步是使用新的拖放助手。在Windows表单中添加一个ListView控件,并用列表项填充它。在事件处理器中,遍历选定的ListView项,并将项文本填充到一个泛型字典中,其中键是临时文件夹中的目标文件,值是源Uri。对于拖放操作,必须指定目标文件存储在临时文件夹中。此外,还需要在StringCollection对象中填充一些临时文件。

private void listView1_ItemDrag(object sender, ItemDragEventArgs e) { if (listView1.SelectedItems.Count == 0) return; StringCollection temporaryFiles = new StringCollection(); IDictionary sourceFiles = new Dictionary(listView1.SelectedItems.Count); foreach (ListViewItem item in listView1.SelectedItems) { if (string.IsNullOrWhiteSpace(item.Text)) continue; string fileName = Path.GetFileName(item.Text); if (string.IsNullOrWhiteSpace(fileName)) continue; string targetFilePath = Path.Combine(Path.GetTempPath(), fileName); temporaryFiles.Add(targetFilePath); sourceFiles.Add(targetFilePath, item.Text); } FileDragDropHelper data = new FileDragDropHelper(file => { KeyValuePair filePair = sourceFiles.FirstOrDefault(fi => string.Equals(fi.Key, file)); if (string.IsNullOrWhiteSpace(filePair.Key) || string.IsNullOrWhiteSpace(filePair.Value)) return; WebRequest request = WebRequest.CreateDefault(new Uri(filePair.Value)); using (WebResponse response = request.GetResponse()) { using (Stream readStream = response.GetResponseStream()) { if (readStream == null || !readStream.CanRead) return; using (FileStream writeStream = new FileStream(filePair.Key, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite)) { byte[] buffer = new byte[16384]; for (int index = readStream.Read(buffer, 0, buffer.Length); index > 0; index = readStream.Read(buffer, 0, buffer.Length)) writeStream.Write(buffer, 0, index); } } }); data.SetFileDropList(temporaryFiles); DoDragDrop(data, DragDropEffects.Copy); }); }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485