WebView2 応用テクニック
JavaScriptから.NETのオブジェクトを使用する
WebView2で表示しているページ内のJavaScriptから、.NETのオブジェクトを使用できます。
メソッドを実行したり、プロパティに設定・参照など行えます。
JavaScriptから.NETのクラスにアクセスする為に、.NETのクラスに公開用の属性定義を追加します。
//C#
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisible(true)]
public class JsCall
{
・・・
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisible(true)]
public class JsCall
{
・・・
webView2.CoreWebView2.AddHostObjectToScriptで、公開設定した.NETのクラスのオブジェクトをJavaScript側に登録します。
これでスクリプト側からアクセスできるようになります。
//C#
//第一引数は、JavaScriptからアクセスするときに使用する名称
//第二引数は、公開設定したクラスのオブジェクト
webView2.CoreWebView2.AddHostObjectToScript("jscall", new JsCall());
//第一引数は、JavaScriptからアクセスするときに使用する名称
//第二引数は、公開設定したクラスのオブジェクト
webView2.CoreWebView2.AddHostObjectToScript("jscall", new JsCall());
html側には、JavaScriptで呼び出し用のコードを記述します。
//JavaScript
//書式:chrome.webview.hostObjects.登録したオブジェクト名;
//メソッドの実行
chrome.webview.hostObjects.jscall.ShowMessage('call .net object test');
//オブジェクトの取得
const jscall = chrome.webview.hostObjects.jscall;
//プロパティアクセス
jscall[100] = 'indexer 100';
alert(await jscall[100]);
//書式:chrome.webview.hostObjects.登録したオブジェクト名;
//メソッドの実行
chrome.webview.hostObjects.jscall.ShowMessage('call .net object test');
//オブジェクトの取得
const jscall = chrome.webview.hostObjects.jscall;
//プロパティアクセス
jscall[100] = 'indexer 100';
alert(await jscall[100]);
プロパティやメソッドの戻り値を参照する場合は非同期(async/await)で実行する必要があります。
async function callProp() {
alert(await chrome.webview.hostObjects.jscall.Prop);
}
alert(await chrome.webview.hostObjects.jscall.Prop);
}
サンプル
Imports System.Runtime.InteropServices Public Class JStoCSobj Private Sub JStoCSobj_Load(sender As Object, e As EventArgs) Handles MyBase.Load InitializeAsync() End Sub Private Async Sub InitializeAsync() Await webView2.EnsureCoreWebView2Async(Nothing) End Sub Private Sub button1_Click(sender As Object, e As EventArgs) Handles button1.Click If webView2.CoreWebView2 Is Nothing Then Return Dim html As New System.Text.StringBuilder() html.AppendLine("<!DOCTYPE html>") html.AppendLine("<html lang='ja'>") html.AppendLine("<head>") html.AppendLine("<script language='javascript' type='text/javascript'>") html.AppendLine(" function callFunc() {chrome.webview.hostObjects.jscall.ShowMessage('call .net object test');}") html.AppendLine(" async function callProp() {") html.AppendLine(" const jscall = chrome.webview.hostObjects.jscall;") html.AppendLine(" jscall.Prop='property access';") html.AppendLine(" alert(await jscall.Prop);") html.AppendLine(" }") html.AppendLine(" async function callIndexer() {") html.AppendLine(" const jscall = chrome.webview.hostObjects.jscall;") html.AppendLine(" jscall[100] = 'indexer 100';") html.AppendLine(" alert(await jscall[100]);") html.AppendLine(" }") html.AppendLine("</script>") html.AppendLine("<head>") html.AppendLine("<body>") html.AppendLine("<h1>JavaScriptから.NETアクセス</h1>") html.AppendLine("<input type='button' value='.NETのメソッドコール' onclick='callFunc();'/>") html.AppendLine("<input type='button' value='.NETのプロパティアクセス' onclick='callProp();'/>") html.AppendLine("<input type='button' value='.NETのインデクサーアクセス' onclick='callIndexer();'/>") html.AppendLine("</body>") html.AppendLine("</html>") 'htmlの内容を表示 webView2.CoreWebView2.NavigateToString(html.ToString()) 'JsCallクラスのオブジェクトをjscallとして登録 webView2.CoreWebView2.AddHostObjectToScript("jscall", New JsCall()) End Sub <ClassInterface(ClassInterfaceType.AutoDual)> <ComVisible(True)> Public Class JsCall 'JavaScriptから実行するメソッド Public Sub ShowMessage(mess As String) MessageBox.Show(mess) End Sub 'JavaScriptからアクセスするプロパティ Public Property Prop As String 'JavaScriptからアクセスするインデクサー Private m_dictionary As New Dictionary(Of Integer, String)() <System.Runtime.CompilerServices.IndexerName("Items")> Default Public Property this(index As Integer) As String Get Return m_dictionary(index) End Get Set m_dictionary(index) = Value End Set End Property End Class End Class
using System.Runtime.InteropServices; public partial class JStoCSobj : Form { public JStoCSobj() { InitializeComponent(); InitializeAsync(); } async void InitializeAsync() { await webView2.EnsureCoreWebView2Async(null); } private void button1_Click(object sender, EventArgs e) { if (webView2.CoreWebView2 == null) return; var html = new StringBuilder(); html.AppendLine("<!DOCTYPE html>"); html.AppendLine("<html lang=’ja'>"); html.AppendLine("<head>"); html.AppendLine("<script language='javascript' type='text/javascript'>"); html.AppendLine(" function callFunc() {chrome.webview.hostObjects.jscall.ShowMessage('call .net object test');}"); html.AppendLine(" async function callProp() {"); html.AppendLine(" const jscall = chrome.webview.hostObjects.jscall;"); html.AppendLine(" jscall.Prop='property access';"); html.AppendLine(" alert(await jscall.Prop);"); html.AppendLine(" }"); html.AppendLine(" async function callIndexer() {"); html.AppendLine(" const jscall = chrome.webview.hostObjects.jscall;"); html.AppendLine(" jscall[100] = 'indexer 100';"); html.AppendLine(" alert(await jscall[100]);"); html.AppendLine(" }"); html.AppendLine("</script>"); html.AppendLine("<head>"); html.AppendLine("<body>"); html.AppendLine("<h1>JavaScriptから.NETアクセス</h1>"); html.AppendLine("<input type='button' value='.NETのメソッドコール' onclick='callFunc();'/>"); html.AppendLine("<input type='button' value='.NETのプロパティアクセス' onclick='callProp();'/>"); html.AppendLine("<input type='button' value='.NETのインデクサーアクセス' onclick='callIndexer();'/>"); html.AppendLine("</body>"); html.AppendLine("</html>"); //htmlの内容を表示 webView2.CoreWebView2.NavigateToString(html.ToString()); //JsCallクラスのオブジェクトをjscallとして登録 webView2.CoreWebView2.AddHostObjectToScript("jscall", new JsCall()); } } [ClassInterface(ClassInterfaceType.AutoDual)] [ComVisible(true)] public class JsCall { //JavaScriptから実行するメソッド public void ShowMessage(string mess) { MessageBox.Show(mess); } //JavaScriptからアクセスするプロパティ public string Prop { get; set; } //JavaScriptからアクセスするインデクサー private Dictionary<int, string> m_dictionary = new Dictionary<int, string>(); [System.Runtime.CompilerServices.IndexerName("Items")] public string this[int index] { get { return m_dictionary[index]; } set { m_dictionary[index] = value; } } }