Асинхронное перетаскивание (и удаление) из приложения UWP - PullRequest
0 голосов
/ 31 января 2019

Я пытаюсь реализовать механизм перетаскивания в моем приложении 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 голосов
/ 01 февраля 2019

Для вашего сценария я предполагаю, что у вас есть две 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);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...