从UWP应用程序异步拖动(和放下)

时间:2019-01-31 09:56:44

标签: c# windows asynchronous winapi uwp

我正在尝试在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();
    });
}

结果,当用户开始将某个项目从我的应用程序拖到另一个应用程序中时,它将在鼠标光标旁边显示一个符号。而且,更糟糕的是,如果用户在我获得拖动延迟的数据之前释放鼠标按钮(拖动时),然后什么也不会发生(就像操作无声地失败了一样)。

我已经考虑过在自己的应用程序上向用户提供一些指示,说明数据何时准备就绪,以便他们可以释放鼠标按钮。但是,有什么更好的方法可以防止这两个问题中的任何一个?

1 个答案:

答案 0 :(得分:0)

对于您来说,我假设您有两个Grid来实现整个“拖放”操作过程。一个网格是源代码管理,另一个是目标。

您说“ 如果用户在我获得拖动延迟的数据之前释放鼠标按钮(在拖动时),那么什么也不会发生(好像操作无声地失败了。)” < / p>

要处理这种情况下,你可以注册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);
    }
}