在 WinForms 中使用 Chromium 浏览网页

在 WinForms 中可以通过自带的 WebBrowser 控件加载网页,但 WebBrowser 使用的是 IE 浏览器内核。我们可以使用 CefSharp 引入 Chromium 内核以获得更好的网页浏览体验

关于 CefSharp

CefSharp 是一个 Chromium 嵌入式框架项目的 .NET 包装器,它是免费和开源的。

CefSharp 是将功能全面的符合标准的 Web 浏览器嵌入 Csharp 或 VB.NET 应用程序的最简单方法。CefSharp 具有用于 WinForms 和 WPF 应用程序的浏览器控件,还具有用于自动化项目的版本。CefSharp 基于 Chromium Embedded Framework,它是 Google Chrome 的开源版本。

CefSharp 没有任何外部依赖关系,完整版本的 CefSharp 仅向应用程序添加了约 80MB。

可以使用 .NET to JavaScript 桥来访问和操纵页面内容。可以以编程方式执行 JavaScript 并将其嵌入到页面中,并在触发 JavaScript 事件时接收回调。可以使用 CefSharp 显示使用 HTML5 构建的嵌入式 UI,或显示远程 Web 内容和 Web 应用程序。

安装

1
Install-Package CefSharp.WinForms

显示

添加浏览器的新实例

1
2
3
4
5
6
7
using CefSharp.WinForms;

// 用代码创建新实例或通过设计器添加
// 如果使用设计器,请将 ChromiumWebBrowser.Address 属性设置为您的Url。

var browser = new ChromiumWebBrowser("www.google.com");
parent.Controls.Add(browser);

从 .NET 调用 JavaScript 方法

从后台在网页上执行一些简单的 JavaScript 脚本

1
2
3
// using CefSharp;

browser.ExecuteScriptAsync("document.body.style.background = 'red';");

如果网页包含多个框架,也可以在子框架上执行脚本

1
2
3
// using CefSharp;

browser.GetBrowser().GetFrame("SubFrame").ExecuteScriptAsync("document.body.style.background = 'red';");

将 .NET 类公开给 JavaScript

JavaScript 的绑定(JSB)允许 JavaScript 和 .Net 之间进行通信。

创建后台类

1
2
3
4
5
6
7
public class BoundObject
{
public int Add(int a, int b)
{
return a + b;
}
}

向 JavaScriptObjectRepository 注册类

1
2
3
4
5
6
7
8
9
10
11
browser.JavascriptObjectRepository.ResolveObject += (sender, e) =>
{
var repo = e.ObjectRepository;
if (e.ObjectName == "boundAsync")
{
BindingOptions bindingOptions = null;
bindingOptions = BindingOptions.DefaultBinder;
bindingOptions = new BindingOptions { CamelCaseJavascriptNames = false, Binder = new MyCustomBinder() });
repo.Register("boundAsync", new BoundObject(), isAsync: true, options: bindingOptions);
}
};

调用 CefSharp.BindObjectAsync

1
2
3
4
5
6
7
8
9
10
(async function()
{
await CefSharp.BindObjectAsync("boundAsync");

boundAsync.add(16, 2).then(function (actualResult)
{
const expectedResult = 18;
assert.equal(expectedResult, actualResult, "16 + 2 = " + expectedResult);
});
})();