前幾天發表瞭 IEBrowser 訪問頁面中變量或者 JSON 數據的文章, 現在想說明一下在 WebBrowser 中, js 腳本如何訪問 .NET 類.
你可以通過 IEBrowser 的 Scripting 屬性或者 WebBrowser 的 ObjectForScripting 屬性來設置可以被 js 腳本訪問的對象. 而在 js 腳本中可以通過 window.external 來調用對象的方法.
為瞭給大傢演示, 在此之前我已經建好瞭一個本地數據庫和對應的數據集, 並添加瞭一個 InsertStudent 方法在數據適配器中, 這些代碼不方便在此展示, 需要看完成演示的朋友, 可以參考文章末尾的演示鏈接, 下面我們看 School 類的代碼:
[ComVisible(true)]public class School{ public string Register ( string email, string realName, int age ) { if ( string.IsNullOrEmpty ( email ) ) return “EMail 不能為空”; if ( string.IsNullOrEmpty ( realName ) ) return “姓名不能為空”; if ( age <= 6 || age > 100 ) return “年齡應該在 7 到 100 之間”; try { SchoolDSTableAdapters.StudentTableAdapter adapter = new SchoolDSTableAdapters.StudentTableAdapter ( ); adapter.InsertStudent ( email, realName, age ); return “註冊成功”; } catch { return “註冊失敗”; } }}School 類是需要使用 ComVisible 屬性來修飾的, ComVisible 設置為 true, School 才能被 js 訪問.
可以看到 School 隻有一個簡單的 Register 註冊方法, 在方法當中, 我們檢查瞭郵箱, 姓名, 年齡等參數的合法性, 然後通過之前建好的數據適配器向數據庫中添加一條學生信息, 而 Register 最終返回一個字符串, js 腳本在調用 Register 方法後, 可以將此字符串顯示給操作者.
下面的代碼是頁面 school.htm, 而這個頁面也就是操作者和程序交互的界面:
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”><html> <head> <title></title> <script type=”text/javascript”> function register() { alert(window.external.Register( document.getElementById(email).value, document.getElementById(realName).value, new Number(document.getElementById(age).value) )); } </script> </head> <body> EMail: <input type=”text” id=”email” /><br /> 姓名: <input type=”text” id=”realName” /><br /> 年齡: <input type=”text” id=”age” /><br /> <input type=”button” value=”註冊” onclick=”register();” /> </body></html>在頁面中, 我們分別定義瞭三個文本框, 用於輸入郵箱, 姓名和年齡, 以及一個註冊用的按鈕, 在按鈕的點擊事件中, 我們調用瞭頁面中的 js 函數 register.
而在 js 函數 register 中, 我們通過 window.external 訪問瞭 School 類的 Register 方法, 傳遞瞭郵箱, 姓名和年齡作為參數, 並彈出瞭返回的字符串.
其實, 寫到這裡 window.external 還並不代表 School 類, 需要我們做最後一步的操作.
最後, 我們在窗口 FormManaged 窗口中, 編寫如下的代碼, 窗口上包含一個名稱為 webBrowser 的 WebBrowser 控件:
public partial class FormManaged : Form{ private readonly IEBrowser ie; public FormManaged ( ) { InitializeComponent ( ); this.ie = new IEBrowser ( this.webBrowser ); } private void FormManaged_Load ( object sender, EventArgs e ) { this.ie.Navigate ( Path.Combine ( AppDomain.CurrentDomain.BaseDirectory, “school.htm” ) ); this.ie.IEFlow.Wait ( new UrlCondition(“w”, “school.htm”, StringCompareMode.Contain) ); this.ie.Scripting = new School ( ); }}在窗口中, 我們定義瞭 IEBrowser 對象 ie 作為窗口類的隻讀字段.
當窗口載入時, 我們首先使用 Navigate 將 WebBrowser 導航到我們編寫的 school.htm 頁面, 此頁面在生成時需要調正為輸出到目錄, 之後我們使用 Wait 方法等待 school.htm 頁面載入完成, 最後通過 Scripting 屬性設置 js 腳本可以訪問 School 類.
Scripting 屬性被設置為一個新的 School 實例時, 也就意味著之前 js 中的 window.external 將表示 School.