How to wait until WebBrowser is completely loaded in VB.NET?
Sounds like you want to catch the DocumentCompleted event of your webbrowser control.
MSDN has a couple of good articles about the webbrowser control - WebBrowser Class has lots of examples, and How to: Add Web Browser Capabilities to a Windows Forms Application
Sometimes if you use JavaScript the DocumentComplete
event don't return the right answer; I use the event ProgressChanged
instead:
Private Sub WebBrowser1_ProgressChanged(sender As Object, e As WebBrowserProgressChangedEventArgs) Handles WebBrowser1.ProgressChanged
Console.WriteLine("Current Progress: " + e.CurrentProgress.ToString)
If e.CurrentProgress = e.MaximumProgress Then
' The maximum progress is reached
load_started = True
End If
' The page is confirmed downloaded after the progress returns to 0
If e.CurrentProgress = 0 Then
If load_started Then
' The page is ready to print or download...
WebBrowser1.Print()
load_started = False
End If
End If
End Sub
Salvete! I needed, simply, a function I could call to make the code wait for the page to load before it continued. After scouring the web for answers, and fiddling around for several hours, I came up with this to solve for myself, the exact dilemma you present. I know I am late in the game with an answer, but I wish to post this for anyone else who comes along.
usage: just call WaitForPageLoad()
just after a call to navigation:
whatbrowser.Navigate("http://www.google.com")
WaitForPageLoad()
another example
we don't combine the navigate feature with the page load, because sometimes you need to wait for a load without also navigating, for example, you might need to wait for a page to load that was started with an invokemember
event:
whatbrowser.Document.GetElementById("UserName").InnerText = whatusername
whatbrowser.Document.GetElementById("Password").InnerText = whatpassword
whatbrowser.Document.GetElementById("LoginButton").InvokeMember("click")
WaitForPageLoad()
Here is the code: You need both subs plus the accessible variable, pageready
.
First, make sure to fix the variable called whatbrowser
to be your webbrowser control
Now, somewhere in your module or class, place this:
Private Property pageready As Boolean = False
#Region "Page Loading Functions"
Private Sub WaitForPageLoad()
AddHandler whatbrowser.DocumentCompleted, New WebBrowserDocumentCompletedEventHandler(AddressOf PageWaiter)
While Not pageready
Application.DoEvents()
End While
pageready = False
End Sub
Private Sub PageWaiter(ByVal sender As Object, ByVal e As WebBrowserDocumentCompletedEventArgs)
If whatbrowser.ReadyState = WebBrowserReadyState.Complete Then
pageready = True
RemoveHandler whatbrowser.DocumentCompleted, New WebBrowserDocumentCompletedEventHandler(AddressOf PageWaiter)
End If
End Sub
#End Region
Technically, there are two issues with the code posted by BGM:
the adding of the handlers in the WaitForPageLoad method is potentially too late. The navigation is initiated before the handlers are added which means that in very rare cases where the browser already has the page it may complete before the handlers are added in which case you will miss the event and sit forever waiting.
The solution is to add the handlers before the navigation starts and remove them after the navigation completed
This means the WaitForPageLoad method needs to be split into two methods. One is called before initiating the navigation. It should set the handlers. The second part does the ReadyState monitoring and cleans up when 'Ready'.
good programming practices is to add a timeout so that a lost (or crashed, or looping) browser doesn't make your code wait forever for the document completed even