DataPackage.SetDataProvider doesn't wait (unlike its documentation states)

≡放荡痞女 提交于 2019-12-29 09:56:14

问题


DataPackage.SetDataProvider's documentation states:

Use the SetDataProvider method when your app ... does not want to supply the data until the target app requests it.

But when I run the following code it calls the callback method immediately.

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);
}

When I change StandardDataFormats.Text to StandardDataFormats.Html it does work as expected (delayed rendering) but then I don't get an option for 'Paste' in applications such as Notepad.

How do I get it to wait for text until it's called from a target app as it is supposed to do according to its documentation?

Additionally:

The DataTransfer.OperationCompleted event is not raised.


回答1:


Clipboard is a bit different from other sharing options because it is a system-wide feature and it can be used quite anywhere. I imagine that is the reason while the CopyTOClipboardAction is executed immediately because the user might want to use the clipboard immediately as well.

This also makes sense, because the user could want to set the clipboard contents and then close the app before pasting. This really means the data must be there because the system couldn't set the contents later anymore.




回答2:


As the document Remarks part:

Use the SetDataProvider method when your app supports a specific format, but does not want to supply the data until the target app requests it.

So if you want to get the content, you should use DataPackageView Class and use the corresponding method to get it. As a example for the StandardDataFormats.Html format,

When you copy the HTML content:

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>");
}

To get the content, you should call the DataPackageView.GetHtmlFormatAsync to get it then the CopyToClipboardAction callback will be triggered.

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

But as for the StandardDataFormats.Text format, the CopyToClipboardAction callback will raised twice, I am not sure if it is by design and I will confirm it.

On the other hand, for your issue about the DataTransfer.OperationCompleted event is not raised, you can see the detailed answer in your another thread ('OperationCompleted' event not raised after 'Paste' operation) to call the following code in your paste handler method.

dataPackageView.ReportOperationCompleted(DataPackageOperation.Copy);


来源:https://stackoverflow.com/questions/50087835/datapackage-setdataprovider-doesnt-wait-unlike-its-documentation-states

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!