从UWP中的WebView获取所选内容

时间:2017-01-25 20:13:07

标签: c# webview uwp

我试图将当前选定的文本从UWP WebView中显示的任意网站获取到用C#编写的UWP应用程序。我尝试了几种方法,但异步调用: -

return await myWebView.InvokeScriptAsync("eval", new string[] { "return document.getSelection.toString();" });

await myWebView.InvokeScriptAsync("eval", new string[] { "document.body.innerHTML = document.getSelection.toString();" });

DataPackage data = await web.CaptureSelectedContentToDataPackageAsync();
return await data.GetView().GetTextAsync();

继续悬挂并造成无限循环。

我已经通过InvokeScriptAsync注入了简单的DOM模型编辑代码,但是只要我尝试使用document.getSelection()或window.getSelection(),整个程序就会永远冻结。

我看过这篇文章Windows UWP - WebView get selected Text但是这似乎对我有用,即使我在PC上工作。

2 个答案:

答案 0 :(得分:0)

  

但是一旦我尝试document.getSelection()或window.getSelection(),整个程序就会永远冻结。

您的js代码不正确,我使用以下代码进行测试。它运作良好。

<WebView x:Name="wv" Source="https://msdn.microsoft.com/en-us/default.aspx"/>
<Button Content="get selected text" Click="Button_Click"></Button>
private async void Button_Click(object sender, RoutedEventArgs e)
{
    try
    {
        string[] arguments = new string[] { @"window.getSelection().toString();" };
        var s = await wv.InvokeScriptAsync("eval", arguments);
    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex.Message);
    }
}

答案 1 :(得分:0)

事实证明,问题是InvokeScriptAsync()似乎在一个函数中,该函数的参数是一个Uri对象作为属性的对象。在我这样做之前(这是行不通的):

private async Task<string> GrabSelectedText(WebView web)
    {
        try
        {
            return await web.InvokeScriptAsync("eval", new string[] { @"window.getSelection().toString();" });

        }catch(Exception e)
        {
            return "Exception from GrabSelectedText: " + e.Message;
        }

    }

但是,通过使用Uri对象作为属性添加对象的其他参数(例如在此处找到的WebViewDOMContentLoadedEventArgs:https://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.controls.webviewdomcontentloadedeventargs?cs-save-lang=1&cs-lang=csharp#code-snippet-1)。

以下代码是我发现的工作原理:

public class MockArgs
{
    private Uri uri;

    private MockArgs(Uri uri)
    {
        this.uri = uri;
    }

    public static MockArgs Create(Uri arg)
    {
        return new MockArgs(arg);
    }
}

/** This is in a separate class that is able to see the above protected class*/
public async void GetSelectedText(WebView sender, MockArgs mockArgs)
    {
        var s = await sender.InvokeScriptAsync("eval", new string[] { @"window.getSelection().toString(); " });
        Debug.WriteLine("selection retreived");
    }

/** This is called from anywhere that needs to get the selected text from a WebView (that can see the above GetSelectedText() method. */
public void TestCode(WebView sender){
        GetSelectedText(sender, MockArgs.Create(args.Uri));
     }