我正在尝试在我的 UWP 应用程序中实现拖放机制,以便可以轻松地将我的应用程序中的项目复制到其他应用程序中。
问题是在拖动操作开始时,我并不总是有应该复制的数据。相反,我等待异步操作完成,然后才更新延迟的数据。
这就是我一直在使用的代码,基本上:
private void myGrid_DragStarting(UIElement sender, DragStartingEventArgs args)
{
var deferral = args.GetDeferral();
args.Data.RequestedOperation = DataPackageOperation.Copy;
someAsyncFunction(async (data) => // this callback might take a few seconds to be invoked
{
//
// ... some code which also invokes another function with "await"
//
args.Data.SetStorageItems(new[] { data });
deferral.Complete();
});
}
因此,当用户开始将项目从我的应用程序拖到另一个应用程序时,它会在鼠标光标旁边有一个 🚫 符号。此外,比这更糟糕的是,如果用户在我获得拖动延迟的数据之前释放鼠标按钮(同时拖动它),那么什么都不会发生(就好像操作静默失败一样)。
我已经考虑过在我自己的应用程序上向用户提供一些指示,说明数据何时准备好以便他们可以释放鼠标按钮。但是有没有更好的方法来防止这两个问题?
最佳答案
对于您的场景,我假设您有两个 Grid 来实现整个“拖放”操作过程。一个网格是源代码控制,另一个是目标。
你说“如果用户在我获得拖动延迟的数据之前释放鼠标按钮(同时拖动它),那么什么都不会发生(就好像操作默默地失败了一样)。”
要处理这种情况,您可以注册 DropCompleted 事件并告诉用户“DropResult”。
我制作了一个简单的代码示例,供您了解整个过程。
<Grid>
<Grid CanDrag="True" Width="100" Height="100" Background="AliceBlue" DragStarting="Grid_DragStarting" DropCompleted="Grid_DropCompleted">
</Grid>
<Grid AllowDrop="True" Width="200" Height="200" Background="LightBlue" VerticalAlignment="Bottom" Drop="Grid_Drop" DragEnter="Grid_DragEnter" DragOver="Grid_DragOver" DragLeave="Grid_DragLeave">
</Grid>
</Grid>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private async void Grid_DragStarting(UIElement sender, DragStartingEventArgs args)
{
Debug.WriteLine("DragStarting");
var deferral = args.GetDeferral();
args.Data.RequestedOperation = DataPackageOperation.Copy;
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
{
await Task.Delay(10000);
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/StoreLogo.png"));
args.Data.SetStorageItems(new[] { file });
deferral.Complete();
});
}
private void Grid_DragLeave(object sender, DragEventArgs e)
{
Debug.WriteLine("DragLeave");
}
private void Grid_DragEnter(object sender, DragEventArgs e)
{
Debug.WriteLine("DragEnter");
}
private void Grid_DragOver(object sender, DragEventArgs e)
{
Debug.WriteLine("DragOver");
if (!e.DataView.Contains(StandardDataFormats.StorageItems))
{
e.DragUIOverride.Caption = "There're no StorageItems!";
e.AcceptedOperation = DataPackageOperation.None;
}
else
{
e.AcceptedOperation = DataPackageOperation.Copy;
}
}
private async void Grid_Drop(object sender, DragEventArgs e)
{
Debug.WriteLine("Drop");
if (e.DataView.Contains(StandardDataFormats.StorageItems))
{
var items = await e.DataView.GetStorageItemsAsync();
if (items.Count > 0)
{
var storageFile = items[0] as StorageFile;
Debug.WriteLine(storageFile.DisplayName);
}
}
}
private void Grid_DropCompleted(UIElement sender, DropCompletedEventArgs args)
{
Debug.WriteLine("DropCompleted");
Debug.WriteLine(args.DropResult);
}
}
关于c# - 从 UWP 应用程序异步拖放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54457866/