.NET桌面程序混合開發之二:在原生WinFrom程序中使用WebView2


本文將介紹如何在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
  • 查找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 異常

在頁面跳轉過程中,WebView2控件會發起一系列事件。而嵌入WebView2的應用會監聽到以下事件:

  • NavigationStarting
  • SourceChanged
  • ContentLoading
  • HistoryChanged
  • NavigationCompleted
    了解更多關於WebView2的導航事件
    events of 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; } }
  1. File > Save All (Ctrl+Shift+S) 保存工程
  2. F5 編譯運行
  3. 應用在訪問非 HTTPS 的網站時顯示警報
    alert

9. 宿主程序與頁面之間的通訊

宿主程序和頁面內容可以使用 postMessage 進行通信如下:

  • WebView2 控件中的 Web 內容可以使用 window.chrome.webview.postMessage 向宿主程序發布消息。宿主程序使用任何注冊到 WebMessageReceived 委托方法處理消息。
  • 主程序使用 CoreWebView2.PostWebMessageAsString 或 CoreWebView2.PostWebMessageAsJSON 將消息發布到 WebView2 控件中的 Web 內容。這些消息由添加到 window.chrome.webview.addEventListener 的處理程序捕獲。

通信機制使用原生功能將消息從 Web 內容傳遞到宿主程序。
在項目中,當 WebView2 控件(通過頁面鏈接)導航到一個頁面時,它會在地址欄中顯示新網頁的 URL 並彈出新網頁的 URL。

  1. 在 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 的初始化是異步的。

  1. 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); }
  1. 為了讓WebView2發送和響應web消息,CoreWebView2初始化后,宿主程序在web內容中注入一個腳本:
    a. 使用 postMessage 將 URL 發送到宿主程序。
    b. 注冊一個事件處理程序以打印從宿主程序發送的消息。

  2. 在 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));"); }
  1. File > Save All (Ctrl+Shift+S) 保存工程
  2. F5 編譯運行
  3. 當通過頁面鏈接訪問到新的URI時,WebView2 控件便會將新頁面地址顯示到地址欄。
    至此,一個 WebView2 應用就完成了。
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM