WebBrowser控件簡介WebBrowser控件由來以久,是一個ActiveX控件。以前可以通過COM引用并使用。但在.Net Framework2.0以后,提供了WebBrowser控件的托管包裝。托管包裝使得在Windows窗體客戶端中顯示網(wǎng)頁更為簡便。使用WebBrowser控件,可以模仿IE的功能進行Web訪問,但不僅僅局限于此,還可以通過禁用默認的IE功能,從而將該控件用作簡單的HTML文檔查看器,甚至可以瀏覽Office各種格式文檔。此外,WebBrowser支持DOM和文本兩種方式修改其承載的內容。這一點意味著沒有必要再把修改的HTML保存到臨時文件,而是直接在內容中實現(xiàn)修改并顯示,提高性能并節(jié)省臨時文件資源消耗??偠灾?,我們可以通過種種方法,到達將Web控件和Windows窗體控件無縫地整合到一個應用程序中的目的。利用WebBrowser瀏覽網(wǎng)頁瀏覽網(wǎng)頁是WebBrowser的老本行,托管包裝后的WebBrowser更加簡便易用。主要幾個方法如下:Navigate(): 導航頁面。與以前版本不同,可以只給定一個參數(shù)即可,即URI。GoBack() / GoForward() /GoHome():向后/向前/回首頁。Stop():Refresh(): 停止加載/刷新以上幾個主要方法是用于導航各個頁面用的,但它們并不是永遠生效。這些方法是否生效,取決于AllowNavigation屬性,默認為true,允許導航。Print():用于打印。(1)WebBrowser中的Html文檔模型我們可以通過DOM或文本的形式返回當前WebBrowser中的HTML文檔:Document: DOM(文檔對象模型)形式的對當前網(wǎng)頁的HTML描述。DocumentText: 文本形式的對當前網(wǎng)頁的HTML描述。DocumentStream: 流形式的HTML描述。關于文本形式的沒有什么好說的,它是最直接的HTML描述,但是難于動態(tài)修改,而相比之下DOM形式的HTML描述則靈活的多,可以任意添加、修改、刪除任意節(jié)點。DOM對象模型主要元素有HtmlDocument,HtmlElement, HtmlNode, HtmlText等等,在此不再啰嗦了。(2)WebBrowser與IE默認情況下,WebBrowser控件功能于IE極其相似,提供基本功能。如:可以通過GoHome(),GoBack(),GoFoward(),Stop(),Refresh()來實現(xiàn)IE工具欄中的主頁、向后、向前、停止、刷新;通過Navigate()來實現(xiàn)IE中的地址欄;通過設置IsWebBrowserContextMenuEnabled= true來實現(xiàn)IE右鍵菜單;通過設置WebBrowserShortcutsEnabled =true來實現(xiàn)IE的快捷鍵等等。同樣在某些特殊需要下,我們可能不希望WebBrowser的行為與IE一樣,比如我們只是希望WebBrowser作為一個Html的顯示器,在這種情況下可把AllowNavigate設置成false來阻止WebBrowser的導航功能;把IsWebBrowserContextMenuEnabled和WebBrowserShortcutsEnabled設置為false來阻止右鍵菜單和快捷鍵等等。從而阻止了WebBrowser的一些IE特性。(3)WebBrowser中的腳本錯誤處理當IE瀏覽器遇到時腳本錯誤,左下角會出現(xiàn)一個黃色圖標,點擊可以查看腳本錯誤的詳細信息,并不會有彈出的錯誤信息框。但是WebBrowser控件則沒有這么聰明,它會彈出錯誤信息框,使得程序顯的很不友好,而且會讓一些自動執(zhí)行的程序暫停。雖然WebBrowser提供了ScriptErrorsSuppressed屬性,經(jīng)過嘗試,結果是令人遺憾的,通過設置該屬性可以解決部分問題,但不能徹底解決。在此探討兩種解決方案:一是通過截獲WebBrowser.Document.Window.Error事件,并阻止WebBrowser繼續(xù)處理錯誤來解決。如下://注冊捕獲控件的錯誤的處理事件
this.WebBrowser.Document.Window.Error +=new HtmlElementErrorEventHandler(Window_Error);
//對錯誤進行處理
void Window_Error(object sender, HtmlElementErrorEventArgs e)
{
e.Handled= true; //阻止其他地方繼續(xù)處理
}
上面的方法可以解決大部分問題,但對于多個框架嵌套等等的情形還是不能很好的解決,于是只能自己動手封裝一個MyWebBrowser了,然后用我們自己的MyWebBrowser來替代WebBrowser。如下:
public class MyWebBrowser: System.Windows.Forms.WebBrowser
{
privateSHDocVw.IWebBrowser2 Iwb2;
protected override void AttachInterfaces(object nativeActiveXObject)
{
Iwb2 = (SHDocVw.IWebBrowser2) nativeActiveXObject;
Iwb2.Silent = true;
base.AttachInterfaces(nativeActiveXObject);
}
protected override void DetachInterfaces()
{
Iwb2 = null;
base.DetachInterfaces();
}
}
這種方法能能很好的解決問題,其實使用過非托管WebBrowser的朋友肯定看出來了,實際上是通過引用SHDocVw繞過托管代碼,直接SHDocVw.IWebBrowser2.Silent= true,最原始的也是最有效的。
利用WebBrowser訪問Office文件剛剛說過瀏覽網(wǎng)頁是WebBrowser的老本行,那么除了本行外,其實他還可以搞點兼職。我們知道,在.Net窗體中是不提供嵌入Office文檔OLE控件的,如果希望嵌Office文檔的話,一個可能的解決方案就是使用WebBrowser控件。其實在IE中就可以嵌入Office文檔,所以WebBrowser具有此功力也很正常,但它帶來的效果確實不錯。操作也很簡單:this.webBrowser1.Navigate(strFileName);只此一句,WebBrowser就會以嵌入的形式打開Office文檔(Word, Excel,PowerPoint,...)了,效果如下圖:使用 WebBrowser控件時的注意事項1、在NET 2.0下的Webbrowser控件是對WebbrowserCOM組件的不完全封裝。所以,在簡便的同時也會出現(xiàn)這樣或那樣的問題。簡便也是有代價的。2、WebBrowser控件異步瀏覽到文檔。在調用Navigate()時,該調用會在文檔完全加載之前將控制權返回給應用程序。如果打算為所包含的文檔實現(xiàn)自動操作,則必須在DocumentCompleted事件在文檔完成加載后發(fā)出通知?;蚴峭ㄟ^IsBusy來判斷當前WebBrowser是否正忙于加載其他文檔。然而,通過實踐,問題卻不是這么簡單。一般情況下,當ReadyState屬性變成READYSTATE_COMPLETE時,Webbrowser控件會通過觸發(fā)DocumentCompleted事件來指示網(wǎng)頁加載完畢。但當加載的網(wǎng)頁包含frame時,可能會多次觸發(fā)該事件,所以不能簡單地通過它來判斷網(wǎng)頁加載完畢。并非每個frame都對應了一個DocumentCompleted事件,只有觸發(fā)了DownloadBegin事件的frame才會有相應的DocumentCompleted事件。另外,最外層的frame總是最后觸發(fā)DocumentCompleted事件。那么怎么準確的判斷頁面加載完畢了呢,以下為一方案: intcounter = 0 ; // 計數(shù)器
private voidwebBrowser_Navigated(objectsender,
WebBrowserNavigatedEventArgs e){
counter ++ ;
}
private voidwebBrowser_DocumentCompleted(object sender,
WebBrowserDocumentCompletedEventArgs e){
counter -- ;
if (counter == 0){
// 加載完畢
}
}
3、在一個項目中有多個WebBrowser控件并且每個控件都加載相同類型的Office文檔(全都是Word或全都是Excel)時,會出現(xiàn)多種問題。最常見的問題發(fā)生在Office命令欄上(命令欄會被禁用)。如果在同一個窗體上有兩個WebBrowser控件,且兩個控件都加載Word文檔,那么只有一組工具欄會是活動的,另外一個則被禁用,無法使用。所以,建議一個項目只使用一個控件,并且一次只瀏覽到一個文檔。
4、要清除WebBrowser控件中的當前內容,使用下面的代碼瀏覽到默認空白頁:
this.webBrowser1.Navigate("about:blank");
參考文章
WebBrowser腳本錯誤的完美解決方案
如何使用WebBrowser控件在.NET中打開Office文檔
Webbrowser控件判斷網(wǎng)頁加載完畢的簡單方法
愛華網(wǎng)



