c# - 从 UWP 应用程序异步拖放

标签 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();
    });
}

因此,当用户开始将项目从我的应用程序拖到另一个应用程序时,它会在鼠标光标旁边有一个 🚫 符号。此外,比这更糟糕的是,如果用户在我获得拖动延迟的数据之前释放鼠标按钮(同时拖动它),那么什么都不会发生(就好像操作静默失败一样)。

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

最佳答案

对于您的场景,我假设您有两个 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/

相关文章:

windows - 静默安装 Haskell 平台

windows - imageMagick 的内存问题?

c - C 中的 Windows 用户主文件夹 (MinGW)

c# - 为 RadGridViewComboBox 列创建数据模板

c# - Protobuf.NET 是否处理 [OnSerializing]? "Non-public member cannot be used with full dll compilation"

javascript - 如何在 JavaScript 中向具有多个异步调用的函数添加回调?

c# - 异步/等待中的多个查询(错误 : IEnumerable does not contain ToListAsync())

ios - 在 UIScrollview 中更新 subview 时滚动期间轻微卡住

c# - 序列化特定类型时如何使 JSON.Net 序列化程序调用 ToString()?

c# - 有做笛卡尔积的好 LINQ 方法吗?