目标:
我想要做的是将GridViewItem
从应用程序的外部的UWP应用 GridView
拖到桌面浏览器。在放置事件期间,我想从互联网上下载文件并创建一个StorageFile
,用于填充DataPackage
。我希望将此StorageFile
复制到桌面。不幸的是,当UWP Drag& Drop(使用SetDataProvider
)使用延期时,只要您离开应用程序窗口,请求就会被激活,您必须使用该对象填充DataPackage
转移。所以,在我看来,我需要使用StorageFile
创建的延迟类型CreateStreamedFileFromUriAsyc
。
每次我开始执行拖放操作时,我都不想预先下载数据。我只是想在我将它放到合法复制的地方时下载数据。
StorageFile
从UWP拖放到资源管理器(桌面)。 StorageFile
创建一个CreateStreamedFileFromUriAsyc
,它会为您提供仅在请求数据时下载数据的StorageFile
。 当我尝试将这两个想法结合起来时,Windows资源管理器会给我错误'界面不受支持'。
如果我使用完全相同的代码,但只是在延迟拖动处理程序中通过调用类似GetBasicPropertiesAsync的内容来获取文件内容,则仅当我在桌面上按住拖动直到下载文件时它才有效。当拖动图标从“禁止”图标变为“复制”时,我可以看到它完成。如果我在完成之前松开鼠标按钮,则不会发生任何复制,也不会出现错误。
显然,我希望拖放下载而不必在延迟处理程序上手动启动它。有任何想法吗?这可能吗?
(是的,我意识到创建正确文件扩展名的代码是错误的/不完整的,但这与此无关......)
//DragStarted Handler in constructor
DragItemsStartedCommand = ReactiveCommand.Create<DragItemsStartingEventArgs>((e) =>
{
_dragItems = e.Items.Cast<ItemViewModel>();
e.Data.Properties.Title = "Transfer file";
e.Data.Properties.Description = "desscription of transfering a file";
e.Data.Properties.FileTypes.Add(StandardDataFormats.StorageItems);
e.Data.SetDataProvider(Windows.ApplicationModel.DataTransfer.StandardDataFormats.StorageItems, OnDeferredStorageFileRequestedHandler);
e.Data.RequestedOperation = DataPackageOperation.Copy;
});
//Deferred request handler
async void OnDeferredStorageFileRequestedHandler(DataProviderRequest request)
{
DataProviderDeferral deferral = request.GetDeferral();
try
{
Task<IEnumerable<StorageFile>> task = null;
await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
{
task = DownloadStorageFiles();
});
var result = await task;
request.SetData(result);
}
catch (Exception ex)
{
// Handle the exception
}
finally
{
deferral.Complete();
Debug.WriteLine("deferral complete!!!");
}
}
//Create StorageFile with deferred loading Task
async Task<IEnumerable<StorageFile>> DownloadStorageFiles()
{
List<StorageFile> storageItems = new List<StorageFile>();
foreach (var item in _dragItems)
{
var request = new RestSharp.RestRequest();
var defaultItemType = ItemType.MSWord;
switch (item.MimeTypeTranslated)
{
case ItemType.GoogleDocument:
case ItemType.GoogleSpreadsheet:
case ItemType.GooglePresentation:
case ItemType.GoogleDrawing:
case ItemType.GoogleScript:
request.Resource = $"files/{item.File.id}/export";
request.AddParameter("mimeType", Statics.ItemTypeDictionary.First(x => x.Value == defaultItemType).Key);
break;
default:
request.Resource = $"files/{item.File.id}";
request.AddParameter("alt", "media");
break;
}
string fileName = "";
if (item.File.name.EndsWith($".{Statics.ItemExtensionDictionary[defaultItemType]}"))
fileName = $"{item.File.name}";
else
fileName = $"{item.File.name}.{Statics.ItemExtensionDictionary[defaultItemType]}";
var uri = account.Client.GetAuthorizedUriForDownload(request);
var thumbnail = RandomAccessStreamReference.CreateFromFile(await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///StoreLogo.png")));
var storageFileDeferred = await StorageFile.CreateStreamedFileFromUriAsync(fileName, uri , thumbnail);
//var props = await storageFileDeferred.GetBasicPropertiesAsync();
storageItems.Add(file);
}
return storageItems;
}
GitHub重现这个问题: https://github.com/limefrogyank/DragDeferredFileToDesktop