C#開發BIMFACE系列53 WinForm程式中使用CefSharp載入模型圖紙1 簡單應用

張傳寧發表於2021-10-20
BIMFACE二次開發系列目錄     【已更新最新開發文章,點選檢視詳細】
C#開發BIMFACE系列53 WinForm程式中使用CefSharp載入模型圖紙1 簡單應用

  在我的部落格《C#開發BIMFACE系列52 CS客戶端整合BIMFACE應用的技術方案》中介紹了多種整合BIMFACE到客戶端程式中的方案。最後推薦大家使用 CefSharp元件與WebView2元件。本篇文章介紹使用CefSharp元件如何整合BIMFACE到客戶端程式中。

一、CefSharp 簡介

CefSharp是一個圍繞Chromium Embedded Framework(CEF)的輕量級.NET包裝器。它是用C++/CLI編寫的。允許開發者在.NET應用程式中嵌入Chromium。可以在C#或VB或任何其他CLR語言中使用。CefSharp同時提供WPF和WinForms Web瀏覽器控制元件實現。

功能特點

  • 免費、開源:https://github.com/cefsharp/CefSharp

  C#開發BIMFACE系列53 WinForm程式中使用CefSharp載入模型圖紙1 簡單應用

  • 完善的文件 

  C#開發BIMFACE系列53 WinForm程式中使用CefSharp載入模型圖紙1 簡單應用      

  C#開發BIMFACE系列53 WinForm程式中使用CefSharp載入模型圖紙1 簡單應用

  • 支援JS、C#、WinForm窗體之間相互通訊與呼叫
  • 相容性較好,支援H5、CSS5、WebGL等
  • 支援獲取Cookies較全面
  • 其他
二、CefSharp 下載

步驟1 新建WinForm專案

新建一個WinForm窗體應用程式,目標框架選擇 .NET Framework 4.5.2,因為新版本的CefSahrp元件最低支援 .NET Framework 4.5.2。

步驟2 通過 NeGet 下載

開啟NeGet

(1)搜尋 CefSharp

(2)選擇 CefSharp.WinForms

(3)選擇最新版本

(4)點選【安裝】按鈕

C#開發BIMFACE系列53 WinForm程式中使用CefSharp載入模型圖紙1 簡單應用

點選【確定】開始安裝。

安裝完成後,專案中自動新增了CefSharp.dll、CefSharp.Core.dll、CefSharp.WinForms.dll 類庫引用。

C#開發BIMFACE系列53 WinForm程式中使用CefSharp載入模型圖紙1 簡單應用

工具箱中也增加了CefSharp控制元件

C#開發BIMFACE系列53 WinForm程式中使用CefSharp載入模型圖紙1 簡單應用

步驟3 編譯專案

編譯 BIMFace.SDK.CSharp.Sample.WinForm 專案,生成如下內容

與 CefSharp 相關的共計32個檔案,2個目錄,檔案大小總計216M。這個尺寸相對於業務系統本身來說已經非常大了,最後製作的安裝包尺寸也會很大。

其中 locales 目錄下是語言包,刪除 zh-CN.pak 之外的所有檔案,總檔案大小可以減少22M左右。

三、CefSharp 整合開發

測試功能設計如下

功能說明

(1)WinForm中載入的網頁來自於 BIMFace.SDK\BIMFace.SDK.CSharp.Sample\Pages\BIMFaceDemo7_3.html,所以Web專案要首先執行。

(2)WinForm 窗體中輸入 BIMFACE FileId,點選【載入模型/圖紙】按鈕,呼叫CefSahrp元件,載入步驟(1)中的網頁。程式碼如下:

 1 // 載入模型/圖紙
 2 private void btnLaodBIMFaceFile_Click(object sender, EventArgs e)
 3 {
 4     string fileId = txtBIMFaceFileId.Text.Trim();
 5     if (string.IsNullOrEmpty(fileId))
 6     {
 7         MessageBox.Show("請填寫 BIMFACE FileId。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
 8         return;
 9     }
10     // 將 ChromiumWebBrowserBindObject 例項物件注入到 js 物件中。網頁中即可呼叫 ChromiumWebBrowserBindObject 類中定義的屬性、方法
11     var objToBind = new ChromiumWebBrowserBindObject();
12     chromiumWebBrowser1.JavascriptObjectRepository.Register("_chromeBrowser", objToBind, true, BindingOptions.DefaultBinder);
13 
14     string url = "https://localhost:44389/Pages/BIMFaceDemo7_3.html?fileId=" + fileId;
15     chromiumWebBrowser1.Load(url);
16 }

(3)網頁中點選【JS 呼叫 C# 方法】按鈕。程式碼如下:

在入口函式中,獲取注入的 ChromiumWebBrowser 物件,名稱為 _chromeBrowser。

按鈕對應的js方法

1 // js 呼叫 C# 方法
2 function callCharpMethod() {
3     // 特別提醒:C# 類中定義的方法名稱採用 Pascal 命名。網頁中呼叫的時候必須將方法名稱的第一個字母改為小寫。否則呼叫不成功。
4     _chromeBrowser.testCalcAdd(6,8)
5         .then(function (response) {
6             alert(response);
7         });
8 }

特別提醒:C# 類中定義的方法名稱採用 Pascal 命名。網頁中呼叫的時候必須將方法名稱的第一個字母改為小寫。否則呼叫不成功。

呼叫的C#方法。定義一個單獨的類,用於在CefSahrp元件載入網頁之前,將其注入到網頁中

(4)WinForm窗體中點選【 C# 呼叫 JS 方法】按鈕。程式碼如下:

 1 // C# 呼叫 JS 方法
 2 private void btnCsharpCallJsMethod_Click(object sender, EventArgs e)
 3 {
 4     Task<JavascriptResponse> jsResponse = chromiumWebBrowser1.EvaluateScriptAsync("jsMethodForCSharpTestCalcSub", 25, 7);
 5 
 6     if (jsResponse.Result != null && jsResponse.Result.Success == false)
 7     {
 8         MessageBox.Show("C#呼叫JS方法發生異常。" + jsResponse.Result.Message
 9             , "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
10     }
11 }

網頁中定義的 jsMethodForCSharpTestCalcSub() 方法如下:

1 // js 方法,供C#呼叫
2 function jsMethodForCSharpTestCalcSub(num1, num2) {
3     /*如果引數需要是複雜型別,則傳遞Json格式的字串,然後反序列化為物件即可使用*/
4 
5     alert('傳入的引數num1:' + num1 + ", num2:" + num2 + '  減法運算 num1 - num2 = ' + (num1 - num2));
6 }

特別說明:

(1)C#定義的方法供JS呼叫,C#方法的返回值型別、引數型別都只能是簡單資料型別,如:int、string、bool 等。

(2)JS定義的方法供C#呼叫,JS方法的返回值型別、引數型別都只能是簡單資料型別,如:int、string、bool 等。

一般來說複雜型別就是一個實體類。如果確實想使用複雜型別,建議的解決方案如下:

將複雜型別序列化為字串,呼叫方將其反序列化之後再使用。

 

關於C#與JS互相通訊,請參考CefSahrp官方文件:https://github.com/cefsharp/CefSharp/wiki/General-Usage#3-how-do-you-expose-a-net-class-to-javascript

四、CefSharp 元件執行分析

1、程式分析

(1)啟動應用程式,CefSharp元件未載入Web網頁時,預設啟動了2個 CefSharp.BrowserSubProcess 子程式。原因是我當前使用的CefSharp是94.4.50版本,每當new CefSharp.WinForms.ChromiumWebBrowser() 一個時,會啟動2個子程式。

(2)CefSharp元件載入Web網頁後,又啟動了2個 CefSharp.BrowserSubProcess 子程式,共計4個子程式。原因是 當 chromiumWebBrowser1.Load(url) 時啟動2個子程式。不同版本的 CefSharp 元件,啟動的子程式數量不同。

2、執行日誌分析

CefSahrp元件載入網頁瀏覽BIMFace模型/圖紙之後,程式目錄多了 GPUCache 目錄、debug.txt 檔案。

GPUCache目錄內容如下。BIMFACE載入模型/圖紙時利用了本地電腦的GPU強大的計算功能,所以產生了快取內容。

debug.txt 內如如下,裡面記錄了網頁的執行過程

五、總結
  • 通過NeGet安裝SDK時,執行時環境會被自動下載到當前專案的bin\debug 或者 bin\Release目錄下。導致整個專案非常大,大約220M左右。
  • 以獨立程式方式執行,消耗記憶體較多。

  如下是我的一個WinForm程式中使用CefSharp元件的執行狀態,其中一個子程式消耗記憶體達到1.5G,太可怕了

  C#開發BIMFACE系列53 WinForm程式中使用CefSharp載入模型圖紙1 簡單應用

  • 當控制元件Dock屬性設定為 Fill,客戶端電腦的縮放與佈局不是100%時,窗體呈現黑邊(嚴重bug),並沒有完全填充父容器。

  C#開發BIMFACE系列53 WinForm程式中使用CefSharp載入模型圖紙1 簡單應用

 

《BIMFace.SDK.CSharp》開源SDK。歡迎大家下載使用。

C#開發BIMFACE系列53 WinForm程式中使用CefSharp載入模型圖紙1 簡單應用
BIMFACE二次開發系列目錄     【已更新最新開發文章,點選檢視詳細】

相關文章