Эквивалент WebBrowser.InvokeScript (String, Object []) в WebView2

Заранее спасибо.

В моем приложении WPF я успешно могу передать сообщение из WPF в JavaScript с помощью метода InvokeScript (String, Object []) WebBrowser. Я передаю свое сообщение в параметре Object [], и оно хорошо принимается кодом JS. (См. Код ниже)

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

Window.xaml

 <Grid>
            <DockPanel> 
                <StackPanel>        
                <TextBox x:Name="txtMessageFromWPF" Width="150" FontSize="20"></TextBox>
                <Button x:Name="btnCallDocument" Click="btnCallDocument_Click" Content="CallDocument" />
                </StackPanel>
                <WebBrowser x:Name="webBrowser" DockPanel.Dock="Top" Margin="30"/>           
            </DockPanel>
        </Grid>

Window.xaml.cs

        private void btnCallDocument_Click(object sender, RoutedEventArgs e)
        {
            webBrowser.InvokeScript("WriteMessageFromWPF", new object[] { this.txtMessageFromWPF.Text });
        }

Код JS:

 <script type="text/javascript">
            function getAlert()
            {
                alert("Hi the page is loaded!!!");
            }
            window.onload = getAlert;
            
            function WriteMessageFromWPF(message){
                document.write("Message from WPF: " + message);
            }
        </script>

person Mishra Saurabh    schedule 10.07.2020    source источник


Ответы (2)


Обновление: версия 2 расширения намного проще и универсальнее. Он использует JSON в качестве «промежуточной станции» - используйте NewtonSoft или встроенный конвертер JSON.

Вот сделанное мной расширение (просто создайте файл класса и вставьте его).

ExecuteScriptFunctionAsync строит строку, необходимую для ExecuteScriptAsync, а затем выполняет ее:

//using Microsoft.Web.WebView2.WinForms; //Uncomment the one you use
//using Microsoft.Web.WebView2.Wpf; //Uncomment the one you use
using Newtonsoft.Json;
using System.Threading.Tasks;

public static class Extensions
{
    public static async Task<string> ExecuteScriptFunctionAsync(this WebView2 webView2, string functionName, params object[] parameters)
    {
        string script = functionName + "(";
        for (int i = 0; i < parameters.Length; i++)
        {
            script += JsonConvert.SerializeObject(parameters[i]);
            if (i < parameters.Length - 1)
            {
                script += ", ";
            }
        }
        script += ");";
        return await webView2.ExecuteScriptAsync(script);
    }
}

Передайте имя функции javascript в качестве первого параметра, а затем параметры функции.

Код позволяет иметь любое количество параметров всех типов, которые могут быть сериализованы в JSON: object, array, string, all numbers, boolean и т. Д.

Пример использования (из вопроса):

private async void btnCallDocument_Click(object sender, RoutedEventArgs e)
{
    await webBrowser.ExecuteScriptFunctionAsync("WriteMessageFromWPF", this.txtMessageFromWPF.Text);
}

Другой пример (это приведет к прокрутке окна вниз):

await webView21.ExecuteScriptFunctionAsync("window.scrollTo", 0, 10000);
person Poul Bak    schedule 10.07.2020
comment
Будет ли ваше расширение (или что-то подобное) работать со встроенным WebView2 в WinUI 3.0 с UWP - например, в этом сценарии? - person nam; 13.07.2020
comment
@nam: я ничего не знаю о WinUI, предлагаю вам попробовать. Вам нужно найти директиву using для WinUI WebView2 - person Poul Bak; 14.07.2020
comment
Имейте в виду, что он действительно пытается превратить ВСЕ в JSON, даже если вы вернете только одну строку. Он будет окружать его кавычками, а javascript экранирует его. - person Brain2000; 07.08.2020
comment
Это правда. Когда ExecuteScriptAsync возвращается, у вас всегда будет строка JSON, которую необходимо десериализовать. То же самое и с WebMessageReceived. - person Poul Bak; 07.08.2020
comment
Как бы вы вернули его в JS? - person spacemonki; 29.06.2021
comment
@spacemonki, вы используете функции javascript, которые вы вызываете с помощью этого метода. Когда функция javascript запускается, вы, конечно, можете сохранить переменные в JS. - person Poul Bak; 29.06.2021

В настоящее время в WebView2 нет прямого эквивалента InvokeScript. Ближайшим из них является CoreWebView2.ExecuteScriptAsync. Этот метод принимает строку сценария для запуска и асинхронно возвращает результат выполнения сценария в виде строки JSON.

Если вы хотите вызвать функцию, вам нужно будет создать строку скрипта для этого и передать ее ExecuteScriptAsync. В вашем примере это означает создание строки WriteMessageFromWPF("...") и предоставление ее ExecuteScriptAsync.

Сложная часть правильно кодирует ваш параметр функции. Если строковый параметр содержит кавычки, вам нужно будет экранировать кавычки с косой чертой или создать неправильный сценарий. Вы должны иметь возможность убрать кавычки с помощью косой черты, используя String.Replace:

string script = "WriteMessageFromWPF(\"" + 
    this.txtMessageFromWPF.Text.Replace("\"", "\\\"")
    + "\")";
await webview2.CoreWebView2.ExecuteScriptAsync(script);
person David Risney    schedule 10.07.2020
comment
У меня есть похожий сценарий, опубликованный здесь на случай, если у кого-то есть предложения / комментарии. - person nam; 29.03.2021