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:

  1. 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'.

  2. 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