C#使用CefSharp實(shí)現(xiàn)內(nèi)嵌網(wǎng)頁詳解
一、示例搭建步驟
先給出本文示例代碼:WpfWithCefSharpDemo。
1. 創(chuàng)建項(xiàng)目
創(chuàng)建一個(gè)WPF項(xiàng)目,比如命名為“WpfWithCefSharpDemo”,Winform項(xiàng)目類似。
2. 創(chuàng)建一個(gè)網(wǎng)頁
嵌入的網(wǎng)頁可以是在線的(即給出一個(gè)URL),也可以是一個(gè)離線的HTML網(wǎng)頁,本文為了演示,在工程里直接創(chuàng)建網(wǎng)頁test.html
,屬性設(shè)置生成操作為內(nèi)容,復(fù)制到輸出目錄為如果較新則復(fù)制。
<!DOCTYPE?html> <html> <head> ????<meta?charset="UTF-8"> ????<title>CefSharp測試</title> ????<script> ????????//?測試在Web中調(diào)用C#的方法 ????????function?callCSharpMethod()?{ ????????????window.cefSharpExample.testMethod("來自JS的調(diào)用"); ????????} ????????//?測試C#調(diào)用JS的方法,只傳遞一個(gè)普通的字符串 ????????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()">調(diào)用C#方法</button> <div?id="jsonTable"></div> </body> </html>
上面的代碼給了相關(guān)的注釋,應(yīng)該很明了:
- JS方法
callCSharpMethod
:用于測試JS調(diào)用C#的方法,其中cefSharpExample
為C#注冊的一個(gè)對象,testMethod
是其一個(gè)方法,JS中方法名首字母是小寫(C#里按規(guī)則是大寫),首字母這里有區(qū)別,要注意一下; - JS方法
displayMessage
和displayJson
:用于測試C#調(diào)用JS的方法,方法定義類似,前者入?yún)⑹且粋€(gè)普通字符串,后者入?yún)⑹且粋€(gè)JSON字符串。 - div元素jsonTable用于展示C#傳來的JSon對象數(shù)據(jù)。
3. 添加CefSharp包
安裝CefSharp程序包,可以在Visual Studio的NuGet包管理器中搜索CefSharp.Wpf并安裝。
4. 添加CefSharp控件
在MainWindow.xaml
中引入CefSharp.Wpf
命名空間(取別名為wpf
,這里隨意),將它的chromium
控件加入到窗體中,順帶加幾個(gè)測試按鈕等:
<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="下面顯示的是網(wǎng)頁內(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對象到網(wǎng)頁"?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#的對象到JS中 ????????????Browser.JavascriptObjectRepository.Settings.LegacyBindingEnabled?=?true; ????????????CefSharpSettings.WcfEnabled?=?true; ????????????//?注冊C#的對象到JS中的代碼必須在Cef的Browser加載之前調(diào)用 ????????????Browser.JavascriptObjectRepository.Register("cefSharpExample",?new?CefSharpExample(),?false, ????????????????options:?BindingOptions.DefaultBinder); ????????} ????????///?<summary> ????????///?Cef瀏覽器控件加載完成后,加載網(wǎng)頁內(nèi)容,可以加載網(wǎng)頁的Url,也可以加載網(wǎng)頁內(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對象 ????????///?</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對象,即傳遞一個(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)頁調(diào)用的該方法名首字母小寫,再提醒一次,這里的區(qū)別要注意。
6. 效果展示
JS調(diào)用C#的方法:黃色方框內(nèi)顯示的網(wǎng)頁內(nèi)容,點(diǎn)擊HTML按鈕調(diào)用C#方法測試。
C#調(diào)用JS的普通方法:藍(lán)色方框內(nèi)顯示的WPF控件,點(diǎn)擊WPF按鈕調(diào)用JS方法
測試。
C#傳遞Json對象給JS的方法:藍(lán)色方框內(nèi),點(diǎn)擊WPF按鈕C#傳遞Json對象到網(wǎng)頁測試。
二、總結(jié)
請對著上面的示例完成一遍,如果做過WPF或Winform原生WebBrowser控件的使用的同學(xué),我們這里做個(gè)WPF自帶WebBrowser控件與CefSharp的優(yōu)劣勢對比結(jié)束本文(來著ChatGPT回答的結(jié)果),歡迎留言討論:
WPF自帶的WebBrowser控件優(yōu)勢:
- WebBrowser控件是WPF自帶的,不需要安裝任何其他的庫或組件。
- WebBrowser控件是基于Internet Explorer內(nèi)核,因此它在Windows操作系統(tǒng)中有天然的兼容性和穩(wěn)定性。
- WebBrowser控件提供了許多與瀏覽器相關(guān)的事件,例如Navigating、Navigated、LoadCompleted等,我們可以通過這些事件對網(wǎng)頁加載和導(dǎo)航進(jìn)行控制和反饋。
WPF自帶的WebBrowser控件劣勢:
- WebBrowser控件使用的是舊版本的IE內(nèi)核,不支持現(xiàn)代HTML5、CSS3等標(biāo)準(zhǔn),而且在性能上也不如CefSharp。
- WebBrowser控件的API相對較少,難以實(shí)現(xiàn)一些高級(jí)功能,例如攔截網(wǎng)頁導(dǎo)航、自定義渲染等。
CefSharp優(yōu)勢:
- CefSharp是基于Chromium項(xiàng)目構(gòu)建的,支持最新的HTML5、CSS3等Web標(biāo)準(zhǔn),并且性能表現(xiàn)更出色。
- CefSharp提供了一套豐富的API,我們可以通過它來實(shí)現(xiàn)多種高級(jí)功能,例如自定義網(wǎng)絡(luò)請求、攔截網(wǎng)頁導(dǎo)航、修改HTML內(nèi)容等。
- CefSharp使用的是多線程模型和硬件加速渲染,不會(huì)阻塞UI線程,同時(shí)具有更好的穩(wěn)定性和安全性。
CefSharp劣勢:
- CefSharp需要安裝額外的庫或組件,增加了開發(fā)的復(fù)雜度。
- CefSharp在某些情況下可能會(huì)出現(xiàn)性能問題,例如在高密度屏幕上渲染時(shí)。
因此,在選擇Web瀏覽器控件時(shí),我們需要根據(jù)具體的需求來選擇。如果只是簡單地展示網(wǎng)頁內(nèi)容,并不需要過多的高級(jí)功能,那么WPF自帶的WebBrowser控件足以滿足需要。但如果需要實(shí)現(xiàn)一些復(fù)雜的功能,例如自定義網(wǎng)絡(luò)請求、攔截網(wǎng)頁導(dǎo)航等,那么CefSharp可能會(huì)更加適合??偟膩碚f,CefSharp相對于WPF自帶的WebBrowser控件,具有更強(qiáng)大的功能和更高的性能表現(xiàn),但使用也相對更加復(fù)雜一些。
到此這篇關(guān)于C#使用CefSharp實(shí)現(xiàn)內(nèi)嵌網(wǎng)頁詳解的文章就介紹到這了,更多相關(guān)C# CefSharp內(nèi)嵌網(wǎng)頁內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在C#使用字典存儲(chǔ)事件示例及實(shí)現(xiàn)自定義事件訪問器
這篇文章主要介紹了在C#使用字典存儲(chǔ)事件示例及實(shí)現(xiàn)自定義事件訪問器的方法,是C#事件編程中的基礎(chǔ)知識(shí),需要的朋友可以參考下2016-02-02C#(.Net)將非托管dll嵌入exe中的實(shí)現(xiàn)
本文主要介紹了C#(.Net)將非托管dll嵌入exe中的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-12-12C#?winform?窗體控件跨線程訪問的實(shí)現(xiàn)
在做winform開發(fā)時(shí),如果在子線程中去設(shè)置主線程中UI控件的屬性,會(huì)出現(xiàn)“跨線程調(diào)用異常”,本文就來介紹一下C#?winform?窗體控件跨線程訪問的實(shí)現(xiàn),感興趣的可以了解一下2023-12-12C#創(chuàng)建SQLite控制臺(tái)應(yīng)用程序詳解
這篇文章主要為大家詳細(xì)介紹了C#創(chuàng)建SQLite控制臺(tái)應(yīng)用程序,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07C#?Winform實(shí)現(xiàn)進(jìn)度條顯示
這篇文章主要為大家詳細(xì)介紹了C#?Winform實(shí)現(xiàn)進(jìn)度條顯示,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07