In my program I want to give 2 input-fields within a webbrowser-window a value and then wait for the user to click a login button. After this, I want the program to break out of the loop when the screen contents "Welcome!" (which it contains after logging in).
But now the problem: When the values for username and password are set, the do-loop starts instantly. So even if I click the login-button, the loop still contains the content of the webpage before the button was clicked and it will loop forever.
How can I solve this? I thought about two ways so far:
- Reread the html code after button clicked so the "Welcome!" will be inside the code and then the loop will break, or
- Wait for the user to press the login-button.
But in both ways I have no real idea how to solve it.
WebBrowserWindow.WebBrowser1.Navigate("[...]")
Do
If WebBrowserWindow.WebBrowser1.ReadyState = WebBrowserReadyState.Complete Then
If WebBrowserWindow.WebBrowser1.Document.Body.InnerHtml.ToString.Contains("Login") Then Exit Do
End If
Application.DoEvents()
Loop
If WebBrowserWindow.WebBrowser1.Document.Body.InnerHtml.ToString.Contains("Login") Then
WebBrowserWindow.WebBrowser1.Document.Window.Frames(2).Document.GetElementById("username").SetAttribute("value", sUser)
WebBrowserWindow.WebBrowser1.Document.Window.Frames(2).Document.GetElementById("password").SetAttribute("value", sPass)
Application.DoEvents()
Dim DocumentCompletedHandler As WebBrowserDocumentCompletedEventHandler = Sub(dcsender As Object, dcargs As WebBrowserDocumentCompletedEventArgs)
If WebBrowserWindow.WebBrowser1.ReadyState = WebBrowserReadyState.Complete Then
RemoveHandler WebBrowserWindow.WebBrowser1.DocumentCompleted, DocumentCompletedHandler
'Put the code that should be executed when the user has logged in here.
MsgBox("it works")
End If
End Sub
AddHandler WebBrowserWindow.WebBrowser1.DocumentCompleted, DocumentCompletedHandler
End If
WebBrowserWindow.Close()
Me.Close()
I noticed the problem when I tried to put the html code in a message box. It just contained the 'old' code.
Thanks in advance
The golden rule of WinForms is: NEVER, EVER use
Application.DoEvents()
to keep your UI responsive! If you need to use it then you are almost always doing something wrong (see: Keeping your UI Responsive and the Dangers of Application.DoEvents).Heavy operations should never be done on the UI thread, but in a background thread. There are multiple ways of taking the work of the UI, for instance Tasks, Threads or using the
BackgroundWorker
.HOWEVER in this case, you don't even need a loop. The
WebBrowser
has got aDocumentCompleted
event that is raised every time a page (or aniframe
inside the page) has loaded completely. Use that to know when to execute your code.Having that said, here's how you'd migrate it to
DocumentCompleted
:Here's a little test project: http://www.mydoomsite.com/sourcecodes/WebBrowser_WaitForUserInteraction.zip
Ultimately, your entire code can be changed to:
Alternatively
...if you think it's too messy having lambdas everywhere, you can fall back to using regular methods: