本文將介紹如何在WinForms中嵌入WebView2,並講到WebView2的主要特征。點擊了解更多WebView2的API。
1. 准備
- Visual Studio 2017 及以上版本
- WebView2運行時,或者安裝Beta,Dev,Canary任一版本的 Microsoft Edge 預覽版。受支持的操作系統有:Windows 11\10\8.1\7
- 推薦使用82.0.488.0以上的Canary(日更)版本。
2. 創建單窗體應用
創那一個只包括主窗體的桌面項目:
- 打開Visual Studio
- 依次點 文件->新建->工程
- 點 創建新的工程
- 選擇 C# Windows Forms App (.NET Framework) ,然后點 Next
- 輸入 工程名稱 和 位置 ,在 Framework下拉列表中,選擇 ** .NET Framework 4.7.2** 或以上版本
- 點 創建
3. 安裝 WebView2 SDK
使用 NuGet 為工程添加 WebView2 SDK
- 在 Solution Explorer 右鍵點擊工程名,在彈出菜單中選擇 Manage NuGet Packages
- 點 Browse
- 選擇 Include prerelease(包含預覽版)
- 在查找框中,輸入WebView2,在結果中選擇 Microsoft.Web.WebView2
- 選擇默認版本並點 Install
- 點 Ok
- 點 File > Save All (Ctrl+Shift+S) ,保存工程
- 點 F5 編譯並運行后,程序的運行結果是一個空窗體
4. 創建一個WebView
在你的應用中添加一個WebView2控件。
- 點 Project > Add Form (Windows Forms)
- 在 Add New Item 窗口中,依次點 Visual C# Items > Web > Windows Forms > Form (Windows Forms) ,然后點 Add
- 點 View > Toolbox
- 在 Toolbox ,點開 WebView2 Windows Forms Control
注意:如果你用的是Visual Studio 2017,在Toolbox中默認是找不到WebView2控件的。若想讓其顯示,則需要依次選 Tools > Options > General 並且將 Automatically Populate Toolbox 設置為 true
- 把 WebView2 控件拖到 Form 窗體上。
- 在 Properties 工具框中,將 Name 屬性設置為 webView。可以使用 分類- 按字母排序 來找到需要的屬性
- WebView2的 Source 屬性用於初始化頁面的URI。將其值設置為:https://www.microsoft.com
- 點 File > Save All (Ctrl+Shift+S) 保存工程
- F5 編譯運行工程
- WebView2 控件中顯示如下:
注意:如果你的是高分辨率顯示器,你需要為窗體應用設置置高分辨率支持
5. 添加控件及處理窗體resize事件
從Toolbox中添加更多控件,並處理窗體的resize事件。
- 點 View > Toolbox
- 在 Toolbox 點 Common Controls
- 把 TextBox 拖動到窗體上
- 在 Properties屬性設置窗口,將Name 屬性設置為 addressBar
- 從 Toolbox 中拖動 Button 控件到窗體上
- 在Properties屬性設置窗口,將Name 屬性設置為 goButton
- 將Text屬性設置為 Go!
- 調整Button大小以適應文字
- 將文本框放在Button左側,並與按鈕文字對齊如下
- 重置窗體大小
- 點 View > Code 打開窗體代碼文件。編寫
Form_Resize
函數處理窗體大小改變時,控件在恰當的位置。 - 刪除如下代碼
public Form1() { InitializeComponent(); }
- 拷貝如下代碼到剛刪除的代碼的相同位置
public Form1() { InitializeComponent(); this.Resize += new System.EventHandler(this.Form_Resize); } private void Form_Resize(object sender, EventArgs e) { webView.Size = this.ClientSize - new System.Drawing.Size(webView.Location); goButton.Left = this.ClientSize.Width - goButton.Width; addressBar.Width = goButton.Left - addressBar.Left; }
- 點**File > Save All (Ctrl+Shift+S) **保存工程
- F5編譯運行,效果如下:
6. 地址導航
在應用中添加地址欄,讓用戶可以通過改變地址欄來改變WebView2展示的內容。
- 在
Form1.cs
中添加CoreWebView2
命名空間,代碼如下:
using Microsoft.Web.WebView2.Core;
- 在窗體設計界面,雙擊Go按鈕,以在
Form1.cs
中添加goButton_Click
事件響應方法,將以下代碼拷到方法中:
private void goButton_Click(object sender, EventArgs e) { if (webView != null && webView.CoreWebView2 != null) { webView.CoreWebView2.Navigate(addressBar.Text); } }
這樣,```goButton_Click```方法就實現了當用戶在地址欄輸入地址並點擊Go按鈕時,WebView2就將顯示址址欄中的地址所代表的頁面內容。
- 點 **File > Save All (Ctrl+Shift+S) **保存工程
- F5編譯並運行
- 在地址欄中輸入你想訪問的地址關點Go,驗證下窗口上顯示的是不是你想要的內容吧。
注意:在地址欄中應輸入完整的URL,如果址址不是以http://
或https://
開頭的話,會遇到ArgumentException
異常
7. Navigation(導航) 事件
在頁面跳轉過程中,WebView2控件會發起一系列事件。而嵌入WebView2的應用會監聽到以下事件:
- NavigationStarting
- SourceChanged
- ContentLoading
- HistoryChanged
- NavigationCompleted
了解更多關於WebView2的導航事件
當一個錯誤發生時,會引發以下事件,可能取決於對錯誤網頁的導航 - SourceChanged
- ContentLoading
- HistoryChanged
以下操作,將為NavigationStarting委托注冊一個處理方法,處理當地址不是Https時,取消頁面請求。通過此例來展示如何使用這些事件。 - 在
Form1.cs
中,做如下代碼更改,添加一個EnsureHttps
方法
public Form1() { InitializeComponent(); this.Resize += new System.EventHandler(this.Form_Resize); webView.NavigationStarting += EnsureHttps; } void EnsureHttps(object sender, CoreWebView2NavigationStartingEventArgs args) { String uri = args.Uri; if (!uri.StartsWith("https://")) { args.Cancel = true; } }
在構造函數中,EnsureHttps
被注冊為WebView2控件的NavigationStarting
的事件處理方法。
- File > Save All (Ctrl+Shift+S) 保存工程
- F5 編譯運行
- 如果訪問HTTPS會打開正常的頁面,如果是HTTP則不會正常訪問
8. 腳本
主程序可以在運行時向WebView2注入JavaScript腳本。可以讓WebView2運行任意的JavaScript,或者添加初始化腳本。注入的JavaScript適用於所有新的頂層文檔和任何子框架,直到JavaScript被刪除。注入的 JavaScript 以特定的時間運行。
- 在創建全局對象后運行注入的JavaScript。
- 在運行HTML文檔中包含的任何其他腳本之前運行注入的JavaScript。
1.例如,在用戶導航到非 HTTPS 站點時,添加發送警報的腳本。修改EnsureHttps
函數,使用ExecuteScriptAsync
方法將腳本注入到網頁內容中,如下圖所示
void EnsureHttps(object sender, CoreWebView2NavigationStartingEventArgs args) { String uri = args.Uri; if (!uri.StartsWith("https://")) { webView.CoreWebView2.ExecuteScriptAsync($"alert('{uri} is not safe, try an https link')"); args.Cancel = true; } }
- File > Save All (Ctrl+Shift+S) 保存工程
- F5 編譯運行
- 應用在訪問非 HTTPS 的網站時顯示警報
9. 宿主程序與頁面之間的通訊
宿主程序和頁面內容可以使用 postMessage
進行通信如下:
- WebView2 控件中的 Web 內容可以使用
window.chrome.webview.postMessage
向宿主程序發布消息。宿主程序使用任何注冊到WebMessageReceived
委托方法處理消息。 - 主程序使用
CoreWebView2.PostWebMessageAsString
或CoreWebView2.PostWebMessageAsJSON
將消息發布到 WebView2 控件中的 Web 內容。這些消息由添加到window.chrome.webview.addEventListener
的處理程序捕獲。
通信機制使用原生功能將消息從 Web 內容傳遞到宿主程序。
在項目中,當 WebView2 控件(通過頁面鏈接)導航到一個頁面時,它會在地址欄中顯示新網頁的 URL 並彈出新網頁的 URL。
- 在
Form1.cs
文件中,更新構造函數並創建InitializeAsync
函數,代碼片段如下:
public Form1() { InitializeComponent(); this.Resize += new System.EventHandler(this.Form_Resize); webView.NavigationStarting += EnsureHttps; InitializeAsync(); } async void InitializeAsync() { await webView.EnsureCoreWebView2Async(null); }
在InitializeAsync
函數里,要用EnsureCoreWebView2Async
awaits 調用方式,因為CoreWebView2 的初始化是異步的。
- CoreWebView2 初始化后,注冊一個事件處理方法來響應
WebMessageReceived
事件。在Form1.cs
文件中,使用以下代碼替換InitializeAsync
並添加UpdateAddressBar
。
async void InitializeAsync() { await webView.EnsureCoreWebView2Async(null); webView.CoreWebView2.WebMessageReceived += UpdateAddressBar; } void UpdateAddressBar(object sender, CoreWebView2WebMessageReceivedEventArgs args) { String uri = args.TryGetWebMessageAsString(); addressBar.Text = uri; webView.CoreWebView2.PostWebMessageAsString(uri); }
-
為了讓WebView2發送和響應web消息,
CoreWebView2
初始化后,宿主程序在web內容中注入一個腳本:
a. 使用postMessage
將 URL 發送到宿主程序。
b. 注冊一個事件處理程序以打印從宿主程序發送的消息。 -
在
Form1.cs
文件中,用以下代碼段修改InitializeAsync
:
async void InitializeAsync() { await webView.EnsureCoreWebView2Async(null); webView.CoreWebView2.WebMessageReceived += UpdateAddressBar; await webView.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync("window.chrome.webview.postMessage(window.document.URL);"); await webView.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync("window.chrome.webview.addEventListener(\'message\', event => alert(event.data));"); }
- File > Save All (Ctrl+Shift+S) 保存工程
- F5 編譯運行
- 當通過頁面鏈接訪問到新的URI時,WebView2 控件便會將新頁面地址顯示到地址欄。
至此,一個 WebView2 應用就完成了。