最近有個WPF的項目,須要頻繁的加載不一樣的網頁並提取網頁的數據,隨後就使用了WebBrowser控件。WPF使用WebBrowser控件獲取網頁,通常步驟是:html
一、使用Navgiate方法或者WebBrowser的Source屬性。web
二、監聽LoadCompleted事件,當該事件觸發時,能夠獲取DOM。oop
因爲我須要查看的網頁比較多,須要依次向WebBrowser控件加載多個指定網址,隨後獲取各個DOM。一開始我是使用WithEvents來聲明WebBrowser控件。可是隨後發現會屢次觸發LoadCompleted事件。隨着歷史Navgiate方法的調用,該LoadCompleted事件會被愈來愈多的觸發。spa
舉個例子來講明:窗體加載時,首次調用Navgiate方法,導航到URL1,此時只會觸發一次LoadCompleted;若是第二次調用Navgiate方法,導航到URL2,此時LoadCompleted將被觸發2次,依次是URL1和URL2;依次類推,當加載不少次後,該事件將屢次觸發。日誌
其實要避免這樣的事情發生,能夠經過手動綁定及解除LoadCompleted事件監聽便可。我單獨寫了一個HtmlLoader類,來完成該操做,該類的詳細代碼以下:code
1 Imports mshtml 2 Public Class HtmlLoader 3 Private mWindow As Window 4 Private wb As WebBrowser 5 Private mURL As String 6 Public Property URL() As String 7 Get 8 Return mURL 9 End Get 10 Set(ByVal value As String) 11 mURL = value 12 End Set 13 End Property 14 15 Private mLoadCompleted As Boolean 16 17 Public Sub New(CurWindow As Window, webBrowser As WebBrowser) 18 mWindow = CurWindow 19 wb = webBrowser 20 End Sub 21 22 Public Sub New(CurWindow As Window, webBrowser As WebBrowser, URL As String) 23 mWindow = CurWindow 24 wb = webBrowser 25 Me.Reload(URL) 26 End Sub 27 28 Public Sub Reload() 29 mLoadCompleted = False 30 If Me.URL Is Nothing OrElse Me.URL.Trim.Length = 0 Then Exit Sub 31 mWindow.Dispatcher.Invoke(Sub() 32 LogNote.WriteLine(wb.Name & "-StartLoad", Me.URL) 33 AddHandler wb.LoadCompleted, AddressOf wb_LoadCompleted 34 'wb.Source = New Uri(Me.URL) 35 wb.Navigate(Me.URL) 36 End Sub) 37 End Sub 38 39 Public Sub Reload(URL As String) 40 Me.URL = URL 41 Reload() 42 End Sub 43 44 Private Sub wb_LoadCompleted(sender As Object, e As NavigationEventArgs) 45 mWindow.Dispatcher.Invoke(Sub() 46 LogNote.WriteLine(wb.Name & "-LoadCompleted", Me.URL) 47 RemoveHandler wb.LoadCompleted, AddressOf wb_LoadCompleted 48 End Sub) 49 mLoadCompleted = True 50 End Sub 51 52 Public Function GetDocument() As HTMLDocument 53 Do Until mLoadCompleted 54 55 Loop 56 Return mWindow.Dispatcher.Invoke(Function() As HTMLDocument 57 Return wb.Document 58 End Function) 59 End Function 60 End Class
這個類接受WebBrowser控件所在窗體、WebBrowser控件對象及定位的URL作爲參數。因爲涉及到UI更新問題,須要使用Window對象的Dispatcher來操做,因此須要傳遞Window。htm
LogNote是我本身寫的日誌靜態類,這裏就不提供代碼了,能夠簡單的將其註釋掉就好了。對象