Перед тем, как начать писать этот вопрос, я пытался решить следующее
// 1. navigate to page
// 2. wait until page is downloaded
// 3. read and write some data from/to iframe
// 4. submit (post) form
Проблема заключалась в том, что если на веб-странице существует iframe, событие DocumentCompleted будет запускаться более одного раза (после завершения каждого документа). Весьма вероятно, что программа попыталась прочитать данные из DOM, которые не были завершены и, естественно, потерпели неудачу.
Но вдруг во время написания этого вопроса «Что, если» монстр вдохновил меня, и я решил проблему, которую пытался решить. Поскольку мне не удалось это сделать из Google, я подумал, что было бы неплохо опубликовать это здесь.
private int iframe_counter = 1; // needs to be 1, to pass DCF test
public bool isLazyMan = default(bool);
/// <summary>
/// LOCK to stop inspecting DOM before DCF
/// </summary>
public void waitPolice() {
while (isLazyMan) Application.DoEvents();
}
private void webBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e) {
if(!e.TargetFrameName.Equals(""))
iframe_counter --;
isLazyMan = true;
}
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) {
if (!((WebBrowser)sender).Document.Url.Equals(e.Url))
iframe_counter++;
if (((WebBrowser)sender).Document.Window.Frames.Count <= iframe_counter) {//DCF test
DocumentCompletedFully((WebBrowser)sender,e);
isLazyMan = false;
}
}
private void DocumentCompletedFully(WebBrowser sender, WebBrowserDocumentCompletedEventArgs e){
//code here
}
Пока, по крайней мере, мой 5-метровый хак работает нормально.
Может быть, я действительно не могу запросить Google или MSDN, но я не могу найти:
«Как использовать событие управления веб-браузером DocumentCompleted в C #?»
Примечание: Узнав много о web-контроле, я обнаружил, что он делает FuNKY.
Даже если вы обнаружите, что документ завершен, в большинстве случаев он не останется таким навсегда. Обновление страницы может быть выполнено несколькими способами - обновление кадра, ajax-подобный запрос или push на стороне сервера (необходимо иметь некоторый элемент управления, который поддерживает асинхронную связь и имеет взаимодействие html или JavaScript). Также некоторые фреймы никогда не будут загружаться, поэтому не стоит ждать их вечно.
В итоге я использовал:
if (e.Url != wb.Url)