.NET混合開發解決方案12 網頁JS呼叫C#方法訪問WinForm或WPF窗體

張傳寧發表於2022-05-10

WebView2控制元件應用詳解系列部落格

.NET桌面程式整合Web網頁開發的十種解決方案 

.NET混合開發解決方案1 WebView2簡介

.NET混合開發解決方案2 WebView2與Edge瀏覽器的區別

.NET混合開發解決方案3 WebView2的程式模型

.NET混合開發解決方案4 WebView2的執行緒模型

.NET混合開發解決方案5 WebView2執行時與分發應用

.NET混合開發解決方案7 WinForm程式中通過NuGet管理器引用整合WebView2控制元件

.NET混合開發解決方案8 WinForm程式中通過設定固定版本執行時的BrowserExecutableFolder屬性整合WebView2控制元件

.NET混合開發解決方案9 WebView2控制元件的導航事件

.NET混合開發解決方案10 WebView2控制元件呼叫網頁JS方法

.NET混合開發解決方案11 網頁JS呼叫C#方法

  在前一篇部落格《.NET混合開發解決方案11 網頁JS呼叫C#方法》中介紹了JS訪問C#方法的簡單實現方式。但是在企業級應用軟體中業務需求可能更加複雜,如JS呼叫C#方法之後,需要訪問宿主的窗體,設定窗體(WinForm、WPF、WinUI、Win32)中的控制元件等。

下面通過一個Demo來講解如何實現JS呼叫C#方法。

業務場景:JS呼叫C#方法,傳遞三個引數,分別是num1、num2、message。C#接收到引數後,呼叫WinFrom窗體中定義的方法,將num1與num2作為引數傳入,並將計算結果顯示在窗體控制元件上。

先看一下示例效果

下面詳細介紹其實現步驟。

步驟1

1、在Frm4JSCallWinForm窗體上新增一個label,用於顯示計算結果,預設值為0,且顏色為黑色。

 2、Frm4JSCallWinForm窗體後臺程式碼中新增如下邏輯方法

步驟2

在主機物件中定義 TestCallCSharpWinForm() 方法,該方法中訪問 Frm4JSCallWinForm 窗體中的 SetResultFromWeb() 方法

在普通的類中如訪問一個窗體有兩種方式

第一種是使用窗體類來例項化一個物件

Frm4JSCallWinForm form = new Frm4JSCallWinForm();

第二種方式直接使用窗體已經例項化之後的物件。

窗體已經執行,說明已經例項化了,如果採用第一種方式,那麼新建立的物件與正在執行的窗體物件不是同一個物件,即使訪問到窗體中定義的方法也無法更新當前窗體上的控制元件屬性。所以必須採用第二種方式。

CustomWebView2HostObject 類 與 窗體 Frm4JSCallWinForm 類是兩個獨立的類,CustomWebView2HostObject 類無法直接獲取當前正在執行的Frm4JSCallWinForm 物件,我們知道一個類中的靜態變數或屬性可以通過類名稱直接訪問,這裡通過一個巧妙的方式來實現,即在 Frm4JSCallWinForm窗體中定義一個公開的靜態的 Frm4JSCallWinForm  物件,在建構函式中賦值為當前執行的物件值。

此時在外部任何類中都可以通過 Frm4JSCallWinForm.Instance 訪問到當前執行的窗體物件。

步驟3

在訪問目標網頁之前,通過webView2.CoreWebView2.AddHostObjectToScript()方法向網頁中注入主機物件,其中第一個引數是自定義名稱(隨意命名),JS中訪問主機物件時就需要與該引數名稱一致。

步驟4

網頁中定義一個測試按鈕,並設定點選事件

點選事件中,第43行獲取主機物件,customWebView2HostObject 與 C#中定義的名稱需要完全相同。

使用主機物件呼叫C#方法,由於呼叫過程是非同步的,所以需要使用 await,方法定義前需要加上 async。

以上四步完成後即實現了JS訪問窗體方法。

相關文章