本文将介绍如何在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;
}
}
  1. File > Save All (Ctrl+Shift+S) 保存工程
  2. F5 编译运行
  3. 应用在访问非 HTTPS 的网站时显示警报

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

.NET桌面程序混合开发之二:在原生WinFrom程序中使用WebView2的更多相关文章

  1. Android混合开发之WebViewJavascriptBridge实现JS与java安全交互

    前言: 为了加快开发效率,目前公司一些功能使用H5开发,这里难免会用到Js与Java函数互相调用的问题,这个Android是提供了原生支持的,不过存在安全隐患,今天我们来学习一种安全方式来满足Js与j ...

  2. Android混合开发之WebView与Javascript交互

    前言: 最近公司的App为了加快开发效率选择了一部分功能采用H5开发,从目前市面的大部分App来讲,大致分成Native App.Web App.Hybrid App三种方式,个人觉得目前以Hybri ...

  3. Android混合开发之WebView使用总结

    前言: 今天修改项目中一个有关WebView使用的bug,激起了我总结WebView的动机,今天抽空做个总结. 混合开发相关博客: Android混合开发之WebView使用总结 Android混合开 ...

  4. ios开发之OC基础-oc小程序

    本系列的文章主要来自于个人在学习前锋教育-欧阳坚老师的iOS开发教程之OC语言教学视频所做的笔记,边看视频,边记录课程知识点.建议大家先过一遍视频,在看视频的过程中记录知识点关键字,把把握重点,然后再 ...

  5. IOS开发之Iphone和Ipad应用程序图标和启动动画

    本文转载至 http://blog.csdn.net/yesjava/article/details/8782060 当我们用xcode开发iphone和ipad应用程序的时候,我们可以用一下表中所显 ...

  6. Android NDK开发之从Java与C互调中详解JNI使用(一)

    生活 这一个礼拜过得真的是苦不堪言,上周因为打球脚踝直接扭伤,肿的想猪蹄一样,然后休息几天消肿了,可以缓慢龟速的行走了,然而五一回来上班第一天,上班鞋子还能穿上,下班脚已插不进鞋子里面了,好吧,又肿回 ...

  7. iBrand 开源电商小程序 (Laravel API+ webpack + gulp + 原生小程序)

    iBrand 社交电商产品正式进入开源过程中了,我们制定了详细的开源计划,目前已经发布了 V1 的版本,后续的版本也在陆续整理完善中. 各个版本功能明细如下图: 3 个版本计划在今年春节前全部完成,可 ...

  8. (56)Linux驱动开发之二

                                                                                             内核基础   1.li ...

  9. iOS 混合开发之 Cordova 实践

    在15年时,之前公司使用 Cordova 做混合开发使用,后来公司没有用到了,现在重新记录下. Cordova (官网:http://cordova.apache.org/)简介: Apache Co ...

  10. 移动混合开发之android文件管理demo

    框架采用cordova,android编译环境为android studio.系统为mac,cordova 环境搭建参考网址:http://cordova.apache.org/docs/en/5.0 ...

随机推荐

  1. 响应式系统与 React

    0x1 React 的历史与应用 应用场景 前端应用开发,如 Meta.Ins.Netflix 的网页版 移动原生应用开发,如 Ins.Discord 结合 Electron 进行桌面应用开发 发展历 ...

  2. jenkins 持续集成和交付——安装与账户安全还有凭证(二)

    前言 jenkins 整理完毕,共二十四章,逐步放出,互相交流学习.学会jenkins 只是第一步,真正的还是多写脚本,然后遇到构建过程的坑,然后解决. 正文 安装jenkins 首先是如何安装jen ...

  3. 重新整理数据结构与算法(c#)—— 树的节点删除[十八]

    前言 你好这里的一个删除,指的是如果删除的叶子节点则直接删除,如果删除的是非叶子节点,则删除的是这颗子树. 这样删除的场景并不多,这种删除方式了解即可. 十七和十六没有放树图,把树图放一下. 正文 节 ...

  4. 函数计算GB镜像秒级启动:下一代软硬件架构协同优化揭秘

    简介: 优化镜像加速冷启动大致分为两种做法:降低绝对延迟和降低冷启动概率.自容器镜像上线以来我们已经通过镜像加速技术,分阶段降低了绝对延迟.本文在此基础上,介绍借助函数计算下一代IaaS底座神龙裸金属 ...

  5. dotnet 提升 ToUpper 性能

    在应用软件启动过程中,客户端应用软件是对性能敏感的.比如在解析命令行参数的时候,有时候需要进行字符串处理逻辑.一般来说命令行参数都是语言文化无关的,在需要进行全大写或全小写转换过程中,采用 ToUpp ...

  6. WebSocket集群分布式改造:实现多人在线聊天室

    前言 书接上文,我们开始对我们的小小聊天室进行集群化改造. 上文地址: [WebSocket入门]手把手搭建WebSocket多人在线聊天室(SpringBoot+WebSocket) 本文内容摘要: ...

  7. selenium项目中遇到的问题总结

    问题:在pycharm中运行用例能成功,在命令行运行提示找不到com包解决办法:添加一个PYTHONPATH的环境变量,值为工程目录的路径 当要查找的文本前后有换行时,用如下方法解决//td[cont ...

  8. 自动生成robot自动化测试用例

    背景:java项目使用swagger管理接口,随着需求的开发接口也有增加,要从swagger界面中去查找出新增的接口是件很费时,效率很低的事情. 适用情况: java项目且适用swagger管理接口 ...

  9. Treap,Splay & LCT 学习笔记

    从二叉搜索树到平衡树 二叉搜索树(Binary Search Tree)是一种二叉树的树形数据结构,它维护一个集合,并保证它的中序遍历按照递增顺序给出了这个集合的所有元素.由此,可以完成插入,删除,查 ...

  10. C#开源的两款功能强大的录屏神器

    ScreenToGif ScreenToGif是一款由C#语言开发且开源的操作简单.免费的屏幕录制和GIF动画制作神器.它可以帮助用户捕捉计算机屏幕上的实时动画,并将其保存为高质量的 GIF 图像格式 ...