DataPackage.SetDataProvider не ждет (в отличие от состояний документации) - PullRequest
0 голосов
/ 29 апреля 2018

Документация DataPackage.SetDataProvider состояния:

Используйте метод SetDataProvider, когда ваше приложение ... не хочет предоставлять данные до тех пор, пока целевое приложение не запросит их.

Но когда я запускаю следующий код, он немедленно вызывает метод обратного вызова.

static void CopyToClipboardReference(string s)
{
    DataPackage dataPackage = new DataPackage();
    reference = s;
    dataPackage.SetDataProvider(StandardDataFormats.Text, CopyToClipboardAction);
    Clipboard.SetContent(dataPackage);
}
static string reference;
static void CopyToClipboardAction(DataProviderRequest request)
{
    //Called immediately!
    request.SetData(reference);
}

Когда я изменяю StandardDataFormats.Text на StandardDataFormats.Html, он работает как ожидалось (отложенный рендеринг), но тогда я не получаю опцию «Вставить» в приложениях, таких как Блокнот.

Как заставить его ждать, пока текст не будет вызван из целевого приложения, как это должно быть сделано в соответствии с его документацией?

Дополнительно

Событие DataTransfer.OperationCompleted не вызывается.

Ответы [ 2 ]

0 голосов
/ 10 мая 2018

В качестве документа Примечания часть:

Используйте метод SetDataProvider, когда ваше приложение поддерживает определенный формат, но не хочет предоставлять данные, пока целевое приложение не запросит их.

Поэтому, если вы хотите получить контент, вы должны использовать DataPackageView Class и использовать соответствующий метод для его получения. В качестве примера для формата StandardDataFormats.Html,

При копировании содержимого HTML:

static void CopyToClipboardReference(string s)
{
    DataPackage dataPackage = new DataPackage();

    reference = s;
    dataPackage.SetDataProvider(StandardDataFormats.Html, CopyToClipboardAction);
    Clipboard.SetContent(dataPackage);
}


static string reference;
static void CopyToClipboardAction(DataProviderRequest request)
{
    //Called immediately!
    request.SetData(reference);
}

private void CopyButton_Click(object sender, RoutedEventArgs e)
{
    CopyToClipboardReference("<Html><Body><h1>Load html string.<h1><Body></Html>");
}

Чтобы получить содержимое, вы должны вызвать DataPackageView.GetHtmlFormatAsync , чтобы получить его, тогда будет вызван обратный вызов CopyToClipboardAction.

async void PasteButton_Click(object sender, RoutedEventArgs e)
{
    var data = Windows.ApplicationModel.DataTransfer.Clipboard.GetContent();
    if (data.Contains(StandardDataFormats.Html))
    {
        string htmlFormat = null;
        {
            htmlFormat = await data.GetHtmlFormatAsync();
        }
    }
}

Но что касается формата StandardDataFormats.Text, обратный вызов CopyToClipboardAction будет повышен дважды, я не уверен, что он задуман, и я это подтвердлю.

С другой стороны, если ваш вопрос о событии DataTransfer.OperationCompleted не возник, вы можете увидеть подробный ответ в другой ветке ( Событие OperationCompleted не возникает после операции вставки ) чтобы вызвать следующий код в вашем методе обработчика вставки.

dataPackageView.ReportOperationCompleted(DataPackageOperation.Copy);
0 голосов
/ 30 апреля 2018

Clipboard немного отличается от других параметров общего доступа, поскольку это общесистемная функция, и ее можно использовать в любом месте. Я полагаю, что причина в том, что CopyTOClipboardAction выполняется немедленно, потому что пользователь может также захотеть немедленно использовать буфер обмена.

Это также имеет смысл, поскольку пользователь может захотеть установить содержимое буфера обмена , а затем закрыть приложение перед вставкой . Это действительно означает, что данные должны быть там, потому что система больше не может устанавливать содержимое позже.

...