Webbrowser control in C# weird behavior - c#

I'm setting a HTML string value to webbrowser.DocumentText. Problem is, sometimes it worked and sometimes it hangs up and not go through the documentcompleted event. what might be the problem?
Please reply, asap..
Thanks,
Jepe

Just a thought: With all the web-'dynam-ism' nowadays, a page is never really in a 'completely-loaded' state. After DocumentComplete, the OnLoad event of the page is fired, then any scripts placed in such an event are fired, and then javascript timers may be used to initiate download/upload of some resource, or a change in page using AJAX, etc.
I believe AJAX calls could cause all kinds of unseen problems with your WebBrowser control; because AJAX can cause multiple Navigating() events to fire during the loading of a page. And for that reason your app would experience multiple DocumentCompleted event fire on that page.
A possible solution could be to monitor the page changes and attempt to find out what possibly got changed. And to do this you may need to look into Notify method.
Called by MSHTML when a change occurs
in the contents of the markup
container with which it is
associated.
This and this discussion may help you coming up with something like following:
HtmlElement target = _webBrowser.Document.GetElementById("somedivthatwillbepopulatedbytheajaxrequest");
if (target != null)
{
target.AttachEventHandler("onpropertychange", new EventHandler(handler));
}

Related

page/control lifecycle

I have usercontrol x in a page, within usercontol x is usercontrol z. I need to do something to usercontrol z after an event fires in usercontrol x. I understand this is very generic, but it just lays out a simple premise for my issue.
Is there a simple way to get a list of all events that fire in the page lifecycle whether I am subscribed to them or not to find out what events fire between Event A on the page and Event B on control z? I would think that there would be something like this when page tracing is turned on, but I don't see any events listed. I imagine that it would be something that the pipeline could generate, maybe I could use reflection to get a list?
I found this topic hard to search against in general, maybe I am using bad keywords...
I did find an old project on codeproject.com, but I was hoping that there would be something more elegant available by now.
*To clarify, I'm looking to generate a list after a postback of every potential event (subscribed or not), in firing order from init to unload, of all controls on a page.
THIS POST: Tracing all events in VB.NET
gets me a little bit closer, however these are lists on a per control basis, not in chronological order.
Enable trace with <%# Page Trace="true" %> in page attribute. that should display life cycle events in sequence.
Well if you're just looking to see what the events are in general, and in what order they fire, check out this article. As far as getting them...well, that depends on what you mean. It could be as simple as getting them through reflection:
EventInfo[] events = this.GetType().GetEvents();
The ASP.NET Page Life Cycle Overview on MSDN lists all of the events fired by a Page from PreInit to Unload. Most of these events fire on any class that inherits from System.Web.UI.Control as well.
Update
Now that I understand your intention better, one possible solution would be to loop through the events of every control and assign an event handler that logs the calling of the event. There is at least one way to retrieve all of the event handlers assigned to an event, and it shouldn't be too difficult to adapt that code to assign an event handler instead.

WebBrowser Control not added to Form

I'm using WBC in my project but I don't need it to be added to the form, I tried to call Navigate method but still get empty string when retrieving
the WBC .DocumentTitle!
Navigate is asynchronous, that means it goes to that web page on another thread and does not wait until it finishes. You are trying to get the Title immediatelly, but it is not set yet.
You should attach to DocumentCompleted event on the WBC and check for title there.
As noted the title can only be retrieved after it has been set. To know when that happens, in addition to DocumentCompleted event there is also a WebBrowser.DocumentTitleChanged event that is convenient and could simplify your logic.
Also, presumably, the latter event would also fire when title changes after the document is loaded via Javascript.

Forms WeBrowser Document Ready event. How do I know when all Ajax calls are complete?

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.
}
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 (or hook up the Mutation events if you are on IE9) 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.
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.
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.
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.
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.

Async. Postbacks cause Page_Init? (C#)

I'm experiencing a very strange problem...
I have a regular ASP.Net webpage with a page_init and a page_load function. It is my understanding(from everywhere I look) that page_init gets called on the first page load(as in, not ever called in a postback) and page_load is called anytime something happens with the page.(It is very hard finding any info about this except for dead links and stuff about the page life cycle)
Well, I have an update panel containing other update panels and other assorted controls. Anytime I edit one of these controls, an async postback happens but instead of only page_load being called, page_init is also called which isn't suppose to happen(and didn't happen before a big codebase change)
So I would like to know anything that might cause this behavior or just if my idea of how page events are called is wrong.
I think you have the wrong idea of the page load life cycle. The OnInit event is called on EVERY request. Having the Page_Init method in your code behind is a shorthand way of wiring up the pages OnInit event.
Now I believe that you are confusing this with the "IsPostBack" property which will be set to true if a page posts back to itself i.e. when you click a Button etc. My guess is what you need to do is add an if statement in your Page_Init method i.e.
if(!IsPostBack){
//Do something to to update the UI
}
Page_Init is definitely called on every page hit, postback or not, exactly the same as Page_Load.
The misconception that Page_Init doesn't get called on every request seems to be a common one.
Are you certain that this wasn't happening before your "big codebase change"?
My suggestion is that you create a simple example of what you're trying to do on a brand new scratch page based on these rules..
http://msdn.microsoft.com/en-us/library/ms178472.aspx
Keep adding complexity as you have it now until it breaks..
It would be difficult to diagnose your issue without the code..
Your Page_Init as well as Page_Load both methods should be called each time.

Why does the updatepanels reload controls outside the updatepanel

I have several UpdatePanels on a page and they have been set with a mode of Conditional. I see a flicker in the controls outside of the UpdatePanels when there is an event that occurs within the UpdatePanel (Say a button click).
The page doesn't post back but the user experiences a "Flicker".
Any idea what might be going on here?
I think you might have got the UpdateMode wrong.
By default it is 'Always' if you change it to 'Conditional' it should fix your problem
Do you have event handlers for controls inside the UpdatePanels that make updates to controls outside of the UpdatePanels?
You could try selectively commenting event handlers until it stops flickering to find the culprit.
I also found Firebug to be useful in these cases - you can see the exact HTML going into the updated regions.
You don't say what the callback inside the UpdatePanel is doing.
If it is updating the contents of the panel itself, it could be be the browser is simply repainting the entire page layout to account for the new content just as it would if you resized the browser window.

Categories