2010-05-06 31 views
51

¿Cómo puedo detectar cuándo se ha completado la carga de un control System.Windows.Forms.WebBrowser?Detectar WebBrowser página completa cargando

He intentado utilizar los eventos Navigate y DocumentCompleted pero ambos se han generado varias veces durante la carga del documento.

+0

¿Cómo está usando C#? ¿Es esta una pregunta de asp.net o estás usando el control del navegador web? – kibibu

+0

@kibibu estoy usando el control WebBrowser. – Neir0

+0

La comparación de AbsolutePath puede no funcionar si la página tiene muchos marcos. Lo intenté de esa manera antes, pero aún no lo he logrado. Todavía estoy atascado con este problema. :(:( –

Respuesta

31

Creo que el evento DocumentCompleted se activará para todos los documentos secundarios que se carguen también (como JS y CSS, por ejemplo). Puede consultar el WebBrowserDocumentCompletedEventArgs en DocumentCompleted y verificar la propiedad Url y compararla con la URL de la página principal.

+0

Eso es lo que descubrí al luchar contra este problema yo mismo. Estaba obteniendo un montón de terminaciones adicionales en cosas como pancartas publicitarias. Descarté cualquier evento que no coincida con la URL que busco y funciona. –

+5

@Loren Pechtel, tengo miedo de decir que hay 3 problemas con este enfoque. Primero, cuando tu url principal (nivel superior) hace que una url del servidor redirija, la url del documento intentas comparar con los cambios. En segundo lugar, está el situación de un marco y la página principal que tiene la misma url que cambia el comportamiento en otros parámetros como referrer, etc. por lo que url es lo mismo. También, redirecciones del lado del cliente: ocurren DESPUÉS de que cree que la página se ha cargado y el control del webbrowser devuelve "todo está bien" para ir ". Si quieres ayuda sobre cómo reducir estos, avísame y puedo darte una respuesta aquí. –

+0

@Paul Kearney - pk siéntase libre de leer mi último comentario a Loren. –

3

No parece desencadenar eventos DocumentCompleted/Navigated para archivos JavaScript o CSS externos, pero sí para iframes. Como dice PK, compare la propiedad WebBrowserDocumentCompletedEventArgs.Url (aún no tengo el karma para hacer un comentario).

2

Si está utilizando WPF hay un evento LoadCompleted.

Si es Windows.Forms, el evento DocumentCompleted debe ser el correcto. Si la página que está cargando tiene marcos, su control WebBrowser disparará el evento DocumentCompleted para cada cuadro (consulte here para obtener más información). Sugeriría verificar la propiedad IsBusy cada vez que se dispare el evento y si es falso, entonces su página estará completamente cargada.

26

hice lo siguiente:

void BrowserDocumentCompleted(object sender, 
     WebBrowserDocumentCompletedEventArgs e) 
{ 
    if (e.Url.AbsolutePath != (sender as WebBrowser).Url.AbsolutePath) 
    return; 

    //The page is finished loading 
} 

La última página cargada tiende a ser el que navegaba a, así que esto debería funcionar.

De here.

+4

funcionan como un amuleto. .. excepto que realmente funciona. – ImGreg

+0

Perfecto, justo lo que necesitaba. Explica por qué a veces aparecía toda la página, y algunas veces solo la página parcial. – Elie

+0

Simplemente cámbielo a (remitente de WebBrowser)) .Url ;-) – juFo

13

anote la dirección URL en DocumentCompleted puede ser diferente de la navegación url debido a la transferencia de servidor o normalización URL (por ejemplo, a navegar a www.microsoft.com y tiene http://www.microsoft.com en Documento Completo)

En las páginas sin marcos, este evento dispara una vez después de completar la carga. En páginas con varios fotogramas, este evento se dispara para cada fotograma de navegación (la navegación de notas se admite dentro de un fotograma, por ejemplo, al hacer clic en un enlace en un fotograma se puede navegar el fotograma a otra página). El marco de navegación de más alto nivel, que puede o no ser el navegador de nivel superior, dispara el evento DocumentComplete final.

En el código nativo que sería compare the sender of the DocumentComplete event to determine if the event is the final event in the navigation or not. Sin embargo, en Windows Forms, el parámetro del remitente no está incluido en WebBrowserDocumentCompletedEventArgs. Puede obtener sink the native event para obtener el valor del parámetro o marcar readystate property of the browser o frame documents en el controlador de eventos DocumentCompleted para ver si todos los marcos están listos.

Hay un prolblem con el método readystate como si un download manager está presente y la navegación es a un archivo descargable, la navegación podría ser cancelada por el administrador de descargas y el estado listo no estará completo.

+0

+1 para detalles y enlaces provistos –

4

Tuve el mismo problema de varios eventos disparados DocumentCompleted y probé todas las sugerencias anteriores. Finalmente, parece que en mi caso ni la propiedad IsBusy funciona bien ni la propiedad Url, pero el ReadyState parece ser lo que necesitaba, porque tiene el estado 'Interactivo' mientras carga los múltiples marcos y obtiene el estado 'Completo' solo después de cargar el último. Por lo tanto, sé cuándo la página está completamente cargada con todos sus componentes.

espero que esto pueda ayudar a otros también :)

16

La siguiente debería funcionar.

private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) 
{ 
    //Check if page is fully loaded or not 
    if (this.webBrowser1.ReadyState != WebBrowserReadyState.Complete) 
     return; 
    else 
     //Action to be taken on page loading completion 
} 
+0

¡Muy útil y simple! –

+1

En mi aplicación, el evento se dispara al menos cuatro veces –

+0

@JackGriffin Esto se debe a que cada iframe también es un documento y por lo tanto activará el evento. Es complicado hacer esto. Puede verificar las Urls mencionadas por Paul en la respuesta anterior, pero esto también puede fallar, como lo describe Erx_VB.NExT.Coder. Si las URL que se van a abrir se encuentran dentro de un determinado conjunto de URL predefinidas, puede saber cómo evitarlas. Por ejemplo, cuando me enfrenté por primera vez a este problema, sabía qué URL se abrirían, así que creé una clase hija de la clase WebBrowser y le agregué información adicional. Entonces, fue fácil (al solicitar el objeto emisor) hacer esto. – Transcendental

0

Usar el evento DocumentCompleted con una página con múltiples marcos anidados no me funcionó.

que utiliza la biblioteca Interop.SHDocVW a emitir el control WebBrowser así:

public class webControlWrapper 
{ 
    private bool _complete; 
    private WebBrowser _webBrowserControl; 

    public webControlWrapper(WebBrowser webBrowserControl) 
    { 
     _webBrowserControl = webBrowserControl; 
    } 

    public void NavigateAndWaitForComplete(string url) 
    { 
     _complete = false; 

     _webBrowserControl.Navigate(url); 

     var webBrowser = (SHDocVw.WebBrowser) _webBrowserControl.ActiveXInstance; 

     if (webBrowser != null) 
      webBrowser.DocumentComplete += WebControl_DocumentComplete; 

     //Wait until page is complete 
     while (!_complete) 
     { 
      Application.DoEvents(); 
     } 
    } 

    private void WebControl_DocumentComplete(object pDisp, ref object URL) 
    { 
     // Test if it's the main frame who called the event. 
     if (pDisp == _webBrowserControl.ActiveXInstance) 
      _complete = true; 
    } 

Este código funciona para mí al navegar a una URL definida por el método de webBrowserControl.Navigate (url), pero don No sé cómo controlar la página completa cuando se hace clic en un botón html con htmlElement.InvokeMember ("clic").

0

Puede usar el evento ProgressChanged; La última vez que se muestra indicará que el documento está completamente procesado:

this.webBrowser.ProgressChanged += new 
WebBrowserProgressChangedEventHandler(webBrowser_ProgressChanged); 
+10

¿Cómo sabrías cuándo fue la última vez que se llamó? – tmorell

Cuestiones relacionadas