views:

56

answers:

5

I am responding to the System.Windows.WebBrowser.DocumentComplete event in my application. However this event fires every time an ajax call completes on the page. I would like to know when the document is ready. Meaning when all calls out have returned. Any ideas?

void WebBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
       {
           //Can fire many times if page has async calls.
       }
A: 

If you control the site you're loading you could create an object for scripting that can be called from your javascript when the page is done loading. See WebBrowser.ObjectForScripting....

EDIT: Per OP comments. He doesn't control the site.

Wil P
You are making the assumption that I own the page. The Browser is a control embedded in a Win Forms application.
Nick
You're right. I am making that assumption. Do you just want the page to be completely loaded before displaying it to the user, or do you need to do something to the data once it's loaded?
Wil P
I want the ability to know when the document is done loading. If AJAX requests are used to populate the page then the above mentioned event fires multiple times per page visit.
Nick
A: 

You can check the Url property of WebBrowserDocumentCompletedEventArgs

if (!e.Url.AbsoluteUri.Contains(".js"))
    return;

I haven't tested this for ajax calls, but it works very well for iframes.

s7orm
Wouldn't that just catch the fact that the *.js had been pulled down? Which wouldn't mean that the ajax calls had completed, right?
Wil P
Does this do more than just check the uri string for ".js"?
Nick
+1  A: 

There isn't an event that is fired when the scripts are done (well, there is IActiveScriptSite::OnLeaveScript, but you can't get your own code into IE's scripting host)

I think you can use IDispatchEx to override the appendChild method and removeChild method for each DOM node and inject a call to your code (e.g. an IAmNotDoneYet function) after calling IE's implementation of these method. The original properties and methods should be accessible via COM interfaces (e.g. IHTMLElement.AppendChild).

You probably want to override the setter method for InnerHTML and OuterHTML properties too. If you want to monitor property change like css/directshow transitions then there are too many methods/properties to hook without scarifying performance.

Sheng Jiang 蒋晟
This sounds cool.
Joshua Evensen
A: 

After much searching, trail and error I decided to add a manual delay. I simple spin up a worker thread and then put this tread to sleep for a couple of seconds. This allows the main ui to work while adding the needed delay.

Nick
A: 

As everyone else has said, there really isnt a particular event you can watch for. If you know what particular element you are waiting for, you can wait until that element appears. IE

while (element == null)
application.doevents

Or something. But that's really about it, honestly. If you find a better way, let me know cause i'd be able to use the hell out of that.

Joshua Evensen