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


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

C#.netWinformHybrid

本文将介绍如何在WinForms中嵌入WebView2,并讲到WebView2的主要特征。点击了解更多WebView2的API。

WebView2运行时,或者安装Beta,Dev,Canary任一版本的 Microsoft Edge 预览版。受支持的操作系统有:Windows 11\10\8.1\7
  • 推荐使用82.0.488.0以上的Canary(日更)版本。
  • https://www.microsoft.com
  • File > Save All (Ctrl+Shift+S) 保存工程
  • F5 编译运行工程
  • WebView2 控件中显示如下:
    编译运行
  • 注意:如果你的是高分辨率显示器,你需要为窗体应用设置置高分辨率支持

    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.PostWebMessageAsStringCoreWebView2.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 应用就完成了。

    相关