👻
WPFにおけるWebView2実装と機能紹介
はじめに
WPFでWebView2を使い始めたときにまず調べたこと、気をつけたことをまとめておきます。
-
初期化の順番
EnsureCoreWebView2Async()
実行前にイベントを設定すると動作しない場合があるため、初期化後に購読する。 -
ユーザーデータフォルダ
Cookieやセッションを維持したい場合はCoreWebView2Environment.CreateAsync(null, path)
で保存先を指定する。 -
イベントの種類
-
NavigationStarting
… 遷移開始時(OAuthコールバック検知などに利用) -
NavigationCompleted
… 遷移完了時(ページ描画後の処理に利用) -
WebMessageReceived
… Webページ ↔ アプリ間のメッセージ受信
-
-
双方向通信の方法
- WPF → Web …
PostWebMessageAsString
/PostWebMessageAsJson
- Web → WPF …
chrome.webview.postMessage()
とWebMessageReceived
- WPF → Web …
-
セキュリティ
外部サイト連携時は送信元ドメインを検証。OAuthではstate
パラメータ検証を必須に。
1. 基本セットアップ
NuGet
Install-Package Microsoft.Web.WebView2
XAML
<Window x:Class="SampleApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wv2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
Title="WebView2 Sample" Height="450" Width="800">
<Grid>
<wv2:WebView2 x:Name="WebView"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"/>
</Grid>
</Window>
C#
using Microsoft.Web.WebView2.Core;
using System;
using System.Threading.Tasks;
using System.Windows;
namespace SampleApp
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Loaded += async (_, __) => await InitializeWebViewAsync();
}
private async Task InitializeWebViewAsync()
{
var env = await CoreWebView2Environment.CreateAsync();
await WebView.EnsureCoreWebView2Async(env);
// イベント購読(初期化後に設定)
WebView.NavigationCompleted += OnNavigationCompleted;
WebView.CoreWebView2.WebMessageReceived += OnWebMessageReceived;
// ページを開く
WebView.Source = new Uri("https://localhost:5001/index.html");
}
private void OnNavigationCompleted(object sender, CoreWebView2NavigationCompletedEventArgs e)
{
MessageBox.Show($"ページロード完了: {WebView.Source}");
}
// Web → WPF
private void OnWebMessageReceived(object sender, CoreWebView2WebMessageReceivedEventArgs e)
{
string message = e.TryGetWebMessageAsString();
MessageBox.Show($"Webからのメッセージ: {message}");
}
// WPF → Web(文字列)
private void SendMessageToWeb()
{
WebView.CoreWebView2.PostWebMessageAsString("Hello from WPF!");
}
// WPF → Web(JSON)
private void SendJsonToWeb()
{
var json = "{\"type\":\"greeting\",\"text\":\"Hello from WPF JSON!\"}";
WebView.CoreWebView2.PostWebMessageAsJson(json);
}
}
}
2. Web側実装例(JavaScript)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>WebView2 Communication</title>
<script>
window.addEventListener("DOMContentLoaded", () => {
// WPFからのメッセージ受信
window.chrome.webview.addEventListener('message', event => {
console.log("WPFから受信:", event.data);
document.getElementById("log").innerText += "\n" + JSON.stringify(event.data);
});
// ボタンクリックでWPFへメッセージ送信
document.getElementById("sendBtn").addEventListener("click", () => {
chrome.webview.postMessage("Hello from Web!");
});
});
</script>
</head>
<body>
<h1>WebView2通信テスト</h1>
<button id="sendBtn">WPFへ送信</button>
<pre id="log"></pre>
</body>
</html>
3. WebView2 の主な機能と用途
機能カテゴリ | 説明 | 実装例 |
---|---|---|
ページ遷移制御 |
Navigate / Source で任意URLへ移動 |
WebView.Source = new Uri(...) |
イベントフック |
NavigationStarting (遷移開始)、NavigationCompleted (遷移完了)、DOMContentLoaded (DOM構築後) |
WebView.NavigationCompleted += ... |
JavaScript実行 | Web側でスクリプトを実行 | await WebView.ExecuteScriptAsync("alert('test')"); |
双方向通信(Web→WPF) | JS → C# メッセージ送信 |
chrome.webview.postMessage() + WebMessageReceived
|
双方向通信(WPF→Web) | C# → JS メッセージ送信 |
PostWebMessageAsString / PostWebMessageAsJson
|
ユーザーデータフォルダ管理 | CookieやLocalStorage保持 | CoreWebView2Environment.CreateAsync(null, path) |
カスタムスキーム対応 | NavigationStartingで検知し処理 | OAuthコールバック検知など |
4. OAuthコールバックの検知例
NavigationCompletedで検知
WebView.NavigationCompleted += (s, e) =>
{
var url = WebView.Source.AbsoluteUri;
if (url.Contains("/auth?res=success"))
{
var query = System.Web.HttpUtility.ParseQueryString(new Uri(url).Query);
var token = query["token"];
MessageBox.Show($"認証成功: token={token}");
}
};
NavigationStartingで即時検知
WebView.CoreWebView2.NavigationStarting += (s, e) =>
{
var uri = new Uri(e.Uri);
if (uri.AbsolutePath == "/auth" && uri.Query.Contains("res=success"))
{
var query = System.Web.HttpUtility.ParseQueryString(uri.Query);
var token = query["token"];
e.Cancel = true; // ページ遷移を止める
MessageBox.Show($"認証成功: token={token}");
}
};
5. 実務での利用シーン
- デスクトップアプリ内でのSPA(React/Vue等)の組み込み
- OAuth / OIDC 認証フローのコールバック処理
- データ可視化ライブラリ(D3.js, Chart.js等)をWPF内に埋め込み
- ローカルアプリからWebサービスへのデータ送信・受信
まとめ
WebView2を使えば、WPFアプリにモダンなWeb機能を統合し、UI/UXを大幅に向上できます。
- ページ遷移検知:
NavigationStarting
/NavigationCompleted
- 双方向通信:
WebMessageReceived
とPostWebMessageAsString/Json
- セキュリティ:必ずドメイン検証や
state
チェックを行う
Discussion