今天爲了應對一個工做中遇到的場景,研究了下使用.NET中自帶的WebBrowser時內部的JS代碼與外部的C#代碼相互調用的問題
html
個人操做系統爲Win7旗艦版,IDE版本爲VS2012,.NET版本爲4.5web
通過測試我得出了以下幾個結論:(C#寫的部分簡稱C,WebBrowser內的頁面代碼簡稱B)c#
一、C調用B的JS代碼,能夠傳參數,能夠接返回值瀏覽器
使用的是 webBrowser.Document.InvokeScript("JS中函數名", new object[] {參數列表})函數
二、B調用C中寫的函數,能夠傳參數,能夠接返回值測試
使用的是 window.external.[C#中的函數名](參數列表)this
下面來講一下我是如何實現它們:spa
一、在C#代碼中調用WebBrowser內頁面的JS函數操作系統
能夠經過WebBrowser控件中的Document.InvokeScript函數實現,不過要爲放置WebBrowser的窗體相關類加特性:設計
[System.Runtime.InteropServices.ComVisible(true)]
沒有這個特性,運行時會報錯:
二、從WebBrowser內的JS代碼中調用C#相關函數
能夠經過JS代碼:window.external.函數名(參數) 來調用C#中同名同參數個數的函數,但瀏覽器控件WebBrowser的ObjectForScripting屬性,須要置成this(這個改動在Load函數中放置便可)
webBrowser.ObjectForScripting = this;
若是不加這行代碼,JS代碼調用C#函數時會報腳本錯誤:
在我寫的一個DEMO程序中,我共設計了5種場景:
場景1:C#程序調用JS函數刷新網頁,輸出再見兩字;測試目標:C#調用JS函數
場景2:C#程序調用JS函數刷新網頁,輸出文字爲用戶輸入的文字;測試目標:C#調用帶參數的JS函數
場景3:C#程序調用JS函數獲取今日的年月日信息(yyyy-MM-dd);測試目標:C#可否正確接收JS函數返回值
場景4:JS調用C#函數,輸出上面↑↑↑(指bulletin)的文字內容;測試目標:JS調用C#應用程序中帶參數的函數
場景5:JS調用C#函數,將左側輸入框中的內容轉大寫後放到右側輸入框中;測試目標:JS調用C#應用程序中帶參數的函數並接收返回值
下面放代碼:
C#端程序FormMain.cs的代碼以下:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace WebBrowserJsTest { [System.Runtime.InteropServices.ComVisible(true)] public partial class FormMain : Form { public FormMain() { InitializeComponent(); } /// <summary> /// Load函數 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void FormMain_Load(object sender, EventArgs e) { try { string path = Environment.CurrentDirectory + "\\WebBrowserJsTest.html"; webBrowser.Navigate(path); webBrowser.ObjectForScripting = this; } catch (Exception ex) { MessageBox.Show(ex.ToString()); } } /// <summary> /// 測試1 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btn4Test1_Click(object sender, EventArgs e) { webBrowser.Document.InvokeScript("sayGoodBye", null); } /// <summary> /// 測試2 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btn4Test2_Click(object sender, EventArgs e) { webBrowser.Document.InvokeScript("changeBulletin", new object[] { txt4Test2.Text }); } /// <summary> /// 測試3 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btn4Test3_Click(object sender, EventArgs e) { object obj = webBrowser.Document.InvokeScript("getTodaysDate", null); MessageBox.Show(obj.ToString()); } /// <summary> /// 測試4 /// </summary> /// <param name="word"></param> public void ShowBulletin(string word) { MessageBox.Show(word); } /// <summary> /// 測試5 /// </summary> /// <param name="word"></param> /// <returns></returns> public string ToUpper(string word) { return word.ToUpper(); } } }
我又寫了另外一個HTML文件,名爲WebBrowserJsTest.html
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta charset="utf-8" /> <title></title> </head> <body> 這是一個測試用的頁面 <hr /> ========輸出都寫在這裏======== <div id="bulletin">你好</div> <hr /> 測試4:JS調用C#函數,輸出上面↑↑↑的文字內容<br /> 測試目標:JS調用C#應用程序中帶參數的函數<br /> <input type="button" id="showBulletin" value="調用C#1" onclick="showBulletin();" /> <hr /> 測試5:JS調用C#函數,將左側輸入框中的內容轉大寫後放到右側輸入框中<br /> 測試目標:JS調用C#應用程序中帶參數的函數並接收返回值<br /> <input type="text" id="inputValue"/> <input type="button" id="toUpper" value="調用C#2" onclick="toUpper();" /> <input type="text" id="returnValue"/> <script> //測試1 function sayGoodBye() { document.getElementById("bulletin").innerHTML = "再見"; } //測試2 function changeBulletin(word) { document.getElementById("bulletin").innerHTML = word; } //測試3 function prefixInteger(num, n) { return (Array(n).join(0) + num).slice(-n); } function getTodaysDate() { var dateNow = new Date(); var year = dateNow.getFullYear(); var month = (dateNow.getMonth() + 1); var day = dateNow.getDate(); return year + "-" + prefixInteger(month, 2) + "-" + prefixInteger(day, 2); } //測試4 function showBulletin() { var word = document.getElementById("bulletin").innerHTML; window.external.ShowBulletin(word); } //測試5 function toUpper() { var word = document.getElementById("inputValue").value; var ret = window.external.ToUpper(word); document.getElementById("returnValue").value = ret; } </script> </body> </html>
寫好這兩段代碼後,就能夠開始測試這些功能了,以下圖測試了按鈕「調用JS3」
END