WebView2 応用テクニック

JavaScriptから.NETのオブジェクトを使用する

WebView2で表示しているページ内のJavaScriptから、.NETのオブジェクトを使用できます。
メソッドを実行したり、プロパティに設定・参照など行えます。

JavaScriptから.NETのクラスにアクセスする為に、.NETのクラスに公開用の属性定義を追加します。

//C#
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisible(true)]
public class JsCall
{
    ・・・

webView2.CoreWebView2.AddHostObjectToScriptで、公開設定した.NETのクラスのオブジェクトをJavaScript側に登録します。
これでスクリプト側からアクセスできるようになります。
//C#
//第一引数は、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]);

プロパティやメソッドの戻り値を参照する場合は非同期(async/await)で実行する必要があります。
async function callProp() {
    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; }
							}
					
						}					
					

参考