大家好,我是沙漠盡頭的狼。
本文居間c# wpf里怎麼使用cefsharp嵌入一個網頁,並給出一個簡單示例演示c#和網頁(js)的交互實現。
一、示例搭建步驟
先给出本文示例代码:WpfWithCefSharpDemo。
1. 創建項目
創建一個wpf項目,比如命名為“wpfwithcefsharpdemo”,winform項目類似。
2. 創建一個網頁
嵌入的网页可以是在线的(即给出一个URL),也可以是一个离线的HTML网页,本文为了演示,在工程里直接创建网页test.html,属性设置生成操作为内容,复制到输出目录为如果较新则复制。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>CefSharp测试</title>
<script>
// 测试在Web中调用C#的方法
function callCSharpMethod() {
window.cefSharpExample.testMethod("来自JS的调用");
}
// 测试C#调用JS的方法,只传递一个普通的字符串
function displayMessage(message) {
alert(message);
}
// 接收C#传递过来的JSON对象,并以表格形式展示在页面上
function displayJson(json) {
var obj = JSON.parse(json);
var html = "<table border='1'>";
for (var prop in obj) {
html += "<tr>";
html += "<td>" + prop + "</td>"
html += "<td>" + obj[prop] + "</td>"
html += "</tr>"
}
html += "</table>";
document.getElementById("jsonTable").innerHTML = html;
}
</script>
</head>
<body>
<h1>CefSharp测试</h1>
<button onclick="callCSharpMethod()">调用C#方法</button>
<div id="jsonTable"></div>
</body>
</html>
上面的代碼給了相關的注釋,應該很明了:
- JS方法
callCSharpMethod:用于测试JS调用C#的方法,其中cefSharpExample为C#注册的一个对象,testMethod是其一个方法,JS中方法名首字母是小写(C#里按规则是大写),首字母这里有区别,要注意一下; - JS方法
displayMessage和displayJson:用于测试C#调用JS的方法,方法定义类似,前者入参是一个普通字符串,后者入参是一个JSON字符串。 - div元素jsontable用於展示c#傳來的json對象數據。
3. 添加cefsharp包
安裝cefsharp程式包,可以在visual studio的nuget包管理器中搜索cefsharp.wpf並安裝。
4. 添加cefsharp控制項
在MainWindow.xaml中引入CefSharp.Wpf命名空间(取别名为wpf,这里随意),将它的chromium控件加入到窗体中,顺带加几个测试按钮等:
<Window x:Class="WpfWithCefSharpDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:wpf="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf"
mc:Ignorable="d"
Title="WPF加载CefSharp测试" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="35"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="50"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Text="下面显示的是网页内容"></TextBlock>
<Border Grid.Row="1" BorderBrush="DarkOrange" BorderThickness="2">
<wpf:ChromiumWebBrowser x:Name="Browser" Loaded="Browser_OnLoaded">
</wpf:ChromiumWebBrowser>
</Border>
<Border Margin="3 5" Grid.Row="2" BorderBrush="Blue" BorderThickness="2" VerticalAlignment="Center">
<StackPanel Orientation="Horizontal" Height="35">
<TextBlock Text="右侧按钮是WPF按钮" VerticalAlignment="Center" Margin="5 3"></TextBlock>
<Button Content="调用JS方法" Click="CallJSFunc_Click" Height="30" Padding="10 2"></Button>
<Button Content="C#传递Json对象到网页" Click="SendJsonToWeb_Click" Height="30" Padding="10 2"></Button>
</StackPanel>
</Border>
</Grid>
</Window>
5. 在c#中調用js方法
在MainWindow.xaml.cs里,添加相关控件的事件处理方法,即C#调用JS方法的相关代码:
using CefSharp;
using Newtonsoft.Json;
using System;
using System.IO;
using System.Text;
using System.Windows;
namespace WpfWithCefSharpDemo
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
// 允许以同步的方式注册C#的对象到JS中
Browser.JavaScriptObjectRepository.Settings.LegacyBindingEnabled = true;
CefSharpSettings.WcfEnabled = true;
// 注册C#的对象到JS中的代码必须在Cef的Browser加载之前调用
Browser.JavaScriptObjectRepository.Register("cefSharpExample", new CefSharpExample(), false,
options: BindingOptions.DefaultBinder);
}
/// <summary>
/// Cef浏览器控件加载完成后,加载网页内容,可以加载网页的Url,也可以加载网页内容
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Browser_OnLoaded(object sender, RoutedEventArgs e)
{
var htmlFile = $"{AppDomain.CurrentDomain.BaseDirectory}test.html";
if (!File.Exists(htmlFile))
{
return;
}
var htmlContent = File.ReadAllText(htmlFile, Encoding.UTF8);
Browser.LoadHtml(htmlContent);
}
/// <summary>
/// C#里调用JS的一般方法
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void CallJSFunc_Click(object sender, RoutedEventArgs e)
{
var jsCode = $"displayMessage('C#里的调用')";
Browser.ExecuteScriptAsync(jsCode);
}
/// <summary>
/// C#调用一个JS的方法,并传递一个JSON对象
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void SendJsonToWeb_Click(object sender, RoutedEventArgs e)
{
var jsonContent = new
{
Id = 1,
Name = "沙漠尽头的狼",
Age = 25,
WebSite="https://dotnet9.com"
};
var jsonStr = JsonConvert.SerializeObject(jsonContent);
// 传递Json对象,即传递一个JSON字符串,和前面的一个示例一样
var jsCode = $"displayJson('{jsonStr}')";
Browser.ExecuteScriptAsync(jsCode);
}
}
public class CefSharpExample
{
public void TestMethod(string message)
{
Application.Current.Dispatcher.Invoke(() => { MessageBox.Show("JS里的调用"); });
}
}
}
CefSharpExample用于封装JS调用的类及方法定义,注意C#这里TestMethod方法名首字母是大写的,前面创建的HTML网页调用的该方法名首字母小写,再提醒一次,这里的区别要注意。
6. 效果展示
JS调用C#的方法:黄色方框内显示的网页内容,点击HTML按钮调用C#方法测试。

C#调用JS的普通方法:蓝色方框内显示的WPF控件,点击WPF按钮调用JS方法测试。

C#传递Json对象给JS的方法:蓝色方框内,点击WPF按钮C#传递Json对象到网页测试。

二、總結
請對著上面的示例完成一遍,如果做過wpf或winform原生webbrowser控制項的使用的同學,我們這裡做個wpf自帶webbrowser控制項與cefsharp的優劣勢對比結束本文(來自chatgpt回答的結果),歡迎留言討論:
wpf自帶的webbrowser控制項優勢:
webbrowser控制項是wpf自帶的,不需要安裝任何其他的庫或組件。
webbrowser控制項是基於internet explorer內核,因此它在windows作業系統中有天然的兼容性和穩定性。
webbrowser控制項提供了許多與瀏覽器相關的事件,例如navigating、navigated、loadcompleted等,我們可以通過這些事件對網頁加載和導航進行控制和反饋。
wpf自帶的webbrowser控制項劣勢:
webbrowser控制項使用的是舊版本的ie內核,不支持現代html5、css3等標準,而且在性能上也不如cefsharp。
webbrowser控制項的api相對較少,難以實現一些高級功能,例如攔截網頁導航、自定義渲染等。
cefsharp優勢:
cefsharp是基於chromium項目構建的,支持最新的html5、css3等web標準,並且性能表現更出色。
cefsharp提供了一套豐富的api,我們可以通過它來實現多種高級功能,例如自定義網絡請求、攔截網頁導航、修改html內容等。
cefsharp使用的是多線程模型和硬體加速渲染,不會阻塞ui線程,同時具有更好的穩定性和安全性。
cefsharp劣勢:
cefsharp需要安裝額外的庫或組件,增加了開發的複雜度。
cefsharp在某些情況下可能會出現性能問題,例如在高密度屏幕上渲染時。
因此,在選擇web瀏覽器控制項時,我們需要根據具體的需求來選擇。如果只是簡單地展示網頁內容,並不需要過多的高級功能,那麼wpf自帶的webbrowser控制項足以滿足需要。但如果需要實現一些複雜的功能,例如自定義網絡請求、攔截網頁導航等,那麼cefsharp可能會更加適合。總的來說,cefsharp相對於wpf自帶的webbrowser控制項,具有更強大的功能和更高的性能表現,但使用也相對更加複雜一些。
參考:
微信技術交流群:添加微信(codewf)備註“入群”
qq技術交流群:771992300。
