C#使用CefSharp實(shí)現(xiàn)內(nèi)嵌網(wǎng)頁(yè)詳解
一、示例搭建步驟
先給出本文示例代碼:WpfWithCefSharpDemo。
1. 創(chuàng)建項(xiàng)目
創(chuàng)建一個(gè)WPF項(xiàng)目,比如命名為“WpfWithCefSharpDemo”,Winform項(xiàng)目類似。
2. 創(chuàng)建一個(gè)網(wǎng)頁(yè)
嵌入的網(wǎng)頁(yè)可以是在線的(即給出一個(gè)URL),也可以是一個(gè)離線的HTML網(wǎng)頁(yè),本文為了演示,在工程里直接創(chuàng)建網(wǎng)頁(yè)test.html,屬性設(shè)置生成操作為內(nèi)容,復(fù)制到輸出目錄為如果較新則復(fù)制。
<!DOCTYPE?html>
<html>
<head>
????<meta?charset="UTF-8">
????<title>CefSharp測(cè)試</title>
????<script>
????????//?測(cè)試在Web中調(diào)用C#的方法
????????function?callCSharpMethod()?{
????????????window.cefSharpExample.testMethod("來自JS的調(diào)用");
????????}
????????//?測(cè)試C#調(diào)用JS的方法,只傳遞一個(gè)普通的字符串
????????function?displayMessage(message)?{
????????????alert(message);
????????}
????????//?接收C#傳遞過來的JSON對(duì)象,并以表格形式展示在頁(yè)面上
????????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測(cè)試</h1>
<button?onclick="callCSharpMethod()">調(diào)用C#方法</button>
<div?id="jsonTable"></div>
</body>
</html>
上面的代碼給了相關(guān)的注釋,應(yīng)該很明了:
- JS方法
callCSharpMethod:用于測(cè)試JS調(diào)用C#的方法,其中cefSharpExample為C#注冊(cè)的一個(gè)對(duì)象,testMethod是其一個(gè)方法,JS中方法名首字母是小寫(C#里按規(guī)則是大寫),首字母這里有區(qū)別,要注意一下; - JS方法
displayMessage和displayJson:用于測(cè)試C#調(diào)用JS的方法,方法定義類似,前者入?yún)⑹且粋€(gè)普通字符串,后者入?yún)⑹且粋€(gè)JSON字符串。 - div元素jsonTable用于展示C#傳來的JSon對(duì)象數(shù)據(jù)。
3. 添加CefSharp包
安裝CefSharp程序包,可以在Visual Studio的NuGet包管理器中搜索CefSharp.Wpf并安裝。
4. 添加CefSharp控件
在MainWindow.xaml中引入CefSharp.Wpf命名空間(取別名為wpf,這里隨意),將它的chromium控件加入到窗體中,順帶加幾個(gè)測(cè)試按鈕等:
<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測(cè)試"?Height="450"?Width="800"> ????<Grid> ????????<Grid.RowDefinitions> ????????????<RowDefinition?Height="35"></RowDefinition> ????????????<RowDefinition?Height="*"></RowDefinition> ????????????<RowDefinition?Height="50"></RowDefinition> ????????</Grid.RowDefinitions> ????????<TextBlock?Text="下面顯示的是網(wǎng)頁(yè)內(nèi)容"></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="右側(cè)按鈕是WPF按鈕"?VerticalAlignment="Center"?Margin="5?3"></TextBlock> ????????????????<Button?Content="調(diào)用JS方法"?Click="CallJSFunc_Click"?Height="30"?Padding="10?2"></Button> ????????????????<Button?Content="C#傳遞Json對(duì)象到網(wǎng)頁(yè)"?Click="SendJsonToWeb_Click"?Height="30"?Padding="10?2"></Button> ????????????</StackPanel> ????????</Border> ????</Grid> </Window>
5. 在C#中調(diào)用JS方法
在MainWindow.xaml.cs里,添加相關(guān)控件的事件處理方法,即C#調(diào)用JS方法的相關(guān)代碼:
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è)C#的對(duì)象到JS中
????????????Browser.JavascriptObjectRepository.Settings.LegacyBindingEnabled?=?true;
????????????CefSharpSettings.WcfEnabled?=?true;
????????????//?注冊(cè)C#的對(duì)象到JS中的代碼必須在Cef的Browser加載之前調(diào)用
????????????Browser.JavascriptObjectRepository.Register("cefSharpExample",?new?CefSharpExample(),?false,
????????????????options:?BindingOptions.DefaultBinder);
????????}
????????///?<summary>
????????///?Cef瀏覽器控件加載完成后,加載網(wǎng)頁(yè)內(nèi)容,可以加載網(wǎng)頁(yè)的Url,也可以加載網(wǎng)頁(yè)內(nèi)容
????????///?</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#里調(diào)用JS的一般方法
????????///?</summary>
????????///?<param?name="sender"></param>
????????///?<param?name="e"></param>
????????private?void?CallJSFunc_Click(object?sender,?RoutedEventArgs?e)
????????{
????????????var?jsCode?=?$"displayMessage('C#里的調(diào)用')";
????????????Browser.ExecuteScriptAsync(jsCode);
????????}
????????///?<summary>
????????///?C#調(diào)用一個(gè)JS的方法,并傳遞一個(gè)JSON對(duì)象
????????///?</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對(duì)象,即傳遞一個(gè)JSON字符串,和前面的一個(gè)示例一樣
????????????var?jsCode?=?$"displayJson('{jsonStr}')";
????????????Browser.ExecuteScriptAsync(jsCode);
????????}
????}
????public?class?CefSharpExample
????{
????????public?void?TestMethod(string?message)
????????{
????????????Application.Current.Dispatcher.Invoke(()?=>?{?MessageBox.Show("JS里的調(diào)用");?});
????????}
????}
}
CefSharpExample用于封裝JS調(diào)用的類及方法定義,注意C#這里TestMethod方法名首字母是大寫的,前面創(chuàng)建的HTML網(wǎng)頁(yè)調(diào)用的該方法名首字母小寫,再提醒一次,這里的區(qū)別要注意。
6. 效果展示
JS調(diào)用C#的方法:黃色方框內(nèi)顯示的網(wǎng)頁(yè)內(nèi)容,點(diǎn)擊HTML按鈕調(diào)用C#方法測(cè)試。

C#調(diào)用JS的普通方法:藍(lán)色方框內(nèi)顯示的WPF控件,點(diǎn)擊WPF按鈕調(diào)用JS方法測(cè)試。

C#傳遞Json對(duì)象給JS的方法:藍(lán)色方框內(nèi),點(diǎn)擊WPF按鈕C#傳遞Json對(duì)象到網(wǎng)頁(yè)測(cè)試。

二、總結(jié)
請(qǐng)對(duì)著上面的示例完成一遍,如果做過WPF或Winform原生WebBrowser控件的使用的同學(xué),我們這里做個(gè)WPF自帶WebBrowser控件與CefSharp的優(yōu)劣勢(shì)對(duì)比結(jié)束本文(來著ChatGPT回答的結(jié)果),歡迎留言討論:
WPF自帶的WebBrowser控件優(yōu)勢(shì):
- WebBrowser控件是WPF自帶的,不需要安裝任何其他的庫(kù)或組件。
- WebBrowser控件是基于Internet Explorer內(nèi)核,因此它在Windows操作系統(tǒng)中有天然的兼容性和穩(wěn)定性。
- WebBrowser控件提供了許多與瀏覽器相關(guān)的事件,例如Navigating、Navigated、LoadCompleted等,我們可以通過這些事件對(duì)網(wǎng)頁(yè)加載和導(dǎo)航進(jìn)行控制和反饋。
WPF自帶的WebBrowser控件劣勢(shì):
- WebBrowser控件使用的是舊版本的IE內(nèi)核,不支持現(xiàn)代HTML5、CSS3等標(biāo)準(zhǔn),而且在性能上也不如CefSharp。
- WebBrowser控件的API相對(duì)較少,難以實(shí)現(xiàn)一些高級(jí)功能,例如攔截網(wǎng)頁(yè)導(dǎo)航、自定義渲染等。
CefSharp優(yōu)勢(shì):
- CefSharp是基于Chromium項(xiàng)目構(gòu)建的,支持最新的HTML5、CSS3等Web標(biāo)準(zhǔn),并且性能表現(xiàn)更出色。
- CefSharp提供了一套豐富的API,我們可以通過它來實(shí)現(xiàn)多種高級(jí)功能,例如自定義網(wǎng)絡(luò)請(qǐng)求、攔截網(wǎng)頁(yè)導(dǎo)航、修改HTML內(nèi)容等。
- CefSharp使用的是多線程模型和硬件加速渲染,不會(huì)阻塞UI線程,同時(shí)具有更好的穩(wěn)定性和安全性。
CefSharp劣勢(shì):
- CefSharp需要安裝額外的庫(kù)或組件,增加了開發(fā)的復(fù)雜度。
- CefSharp在某些情況下可能會(huì)出現(xiàn)性能問題,例如在高密度屏幕上渲染時(shí)。
因此,在選擇Web瀏覽器控件時(shí),我們需要根據(jù)具體的需求來選擇。如果只是簡(jiǎn)單地展示網(wǎng)頁(yè)內(nèi)容,并不需要過多的高級(jí)功能,那么WPF自帶的WebBrowser控件足以滿足需要。但如果需要實(shí)現(xiàn)一些復(fù)雜的功能,例如自定義網(wǎng)絡(luò)請(qǐng)求、攔截網(wǎng)頁(yè)導(dǎo)航等,那么CefSharp可能會(huì)更加適合??偟膩碚f,CefSharp相對(duì)于WPF自帶的WebBrowser控件,具有更強(qiáng)大的功能和更高的性能表現(xiàn),但使用也相對(duì)更加復(fù)雜一些。
到此這篇關(guān)于C#使用CefSharp實(shí)現(xiàn)內(nèi)嵌網(wǎng)頁(yè)詳解的文章就介紹到這了,更多相關(guān)C# CefSharp內(nèi)嵌網(wǎng)頁(yè)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在C#使用字典存儲(chǔ)事件示例及實(shí)現(xiàn)自定義事件訪問器
這篇文章主要介紹了在C#使用字典存儲(chǔ)事件示例及實(shí)現(xiàn)自定義事件訪問器的方法,是C#事件編程中的基礎(chǔ)知識(shí),需要的朋友可以參考下2016-02-02
C#(.Net)將非托管dll嵌入exe中的實(shí)現(xiàn)
本文主要介紹了C#(.Net)將非托管dll嵌入exe中的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-12-12
C#?winform?窗體控件跨線程訪問的實(shí)現(xiàn)
在做winform開發(fā)時(shí),如果在子線程中去設(shè)置主線程中UI控件的屬性,會(huì)出現(xiàn)“跨線程調(diào)用異常”,本文就來介紹一下C#?winform?窗體控件跨線程訪問的實(shí)現(xiàn),感興趣的可以了解一下2023-12-12
C#創(chuàng)建SQLite控制臺(tái)應(yīng)用程序詳解
這篇文章主要為大家詳細(xì)介紹了C#創(chuàng)建SQLite控制臺(tái)應(yīng)用程序,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07
C#?Winform實(shí)現(xiàn)進(jìn)度條顯示
這篇文章主要為大家詳細(xì)介紹了C#?Winform實(shí)現(xiàn)進(jìn)度條顯示,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07

