I'm writing a program to navigate a website, but I'm having trouble with code execution occuring when I don't want it to execute.
I have a WebBrowser control where once the page finishes loading, I have code analyzing the html, and for certain circumstances I tell the WebBrowser to navigate to a new URL.
So I basically have a line of code that looks like this, within a method, the method within the DocumentCompleted handler
if this condition then
wb.Navigate(new Uri("http://www.website.com"), "_self");
else do something else, exit method, continue processing code
However, when I Navigate, the code continunes to execute beyond the Navigate. It exits the method, and keeps processing code.
How to I stop the DocuemntComplete event handler from processing whenever I call a new page navigation?
Related
I'm having trouble my application which is supposed to write text in some textboxes on a website and click OK button. But then the problem comes, the site loads a new page and you have to confirm the previous commands by clicking a new OK button. What I need help with is for my C# code to execute the commands as they are called and no do them once the running thread is dead.
Example of my code:
private void startScript_Click(object sender, EventArgs e)
{
webBrowser1.Document.GetElementById("login_box").InnerText = "NAME";
webBrowser1.Document.GetElementById("password_box").InnerText = "PASS";
webBrowser1.Document.GetElementById("login_button").InvokeMember("click");
//This is where i want the first texts and click to be submitted so it then
//can click on the confirm button the the next page
webBrowser1.Document.GetElementById("confirm_login").InvokeMember("click");
//Submit the confirm click
} //This is where all the information given in the code is actually given/executed to the browser
So to clear up the question. What I need to do is; give the information to the browser directly when the webBrowser1.Document...; is called. A command to submit would also work (webBrowser1.SubmitData) or something like that.
The WebBrowser navigation, which is taking place when you click the button, is an asynchronous operation, it doesn't complete instantly.
I can't guess what your code is doing immediately after InvokeMember("click"), but if you're trying to access WebBrowser.Document right away, or doing something like Thread.Sleep, that won't work. It worked when followed with MessageBox.Show, because MessageBox.Show runs its own modal message loop.
You need to handle WebBrowser.DocumentCompleted first and then access the document. There are a few ways of doing that, here is one of them.
There is a web page (call it main) that contains several frames.
The main and all its included frames raise event DocumentCompleted.
The order of those events is: Subframe1, subframe2, subframeX.., main.
What I want is to parse the content of the main and add some handlers on several html elements on it before the user can take any action. (For example button.Click or link.Click). Till now this is possible by waiting the DocumentCompleted and checking the event's arguments for the correct frame.
However, sometimes the included frames happen to take much time to load and the desired event is not raised within a reasonal amount of time. However the page is visible by the user despite the fact that parsing and the addition of the handlers cannot be done.
So the impatient user interacts with the page, which messes up all the work.
Is there a recommended way to parse the page sooner without waiting for DocumentCompleted (as long as the data is there of course) and keep doing it silently (that is: not show a waiting form or popup to the user)?
You can use the 'Navigated' event, look here
In windows form on click on Next I need to display other form and start some processing. Am coding in .Net C#
The problem is before the form is complete visible, the method gets triggered and the processing starts and the UI looks like it crashed. Processing started even before controls are loaded. and once processing is done all controls are visible.
The actual output must be all controls should be loaded and then processing must start.
I need to call the method to start processing after the form (user control) is visible and is loaded completely.
I tried this and this, but no luck.
Added code:
private void FeatureRemovalControl_Load(object sender, EventArgs e)
{
pictureBox2.Image = Properties.Resources.line;
prgbar.Value = 0;
//code to load images and some other stuff
StratProcess();
}
You're calling StartProcess (which seems to block until it's finished) from your UI thread. Because WinForms repaints occur on that thread, nothing is painted, and it appears that your process has hung. You should look at using a BackgroundWorker, or other way to call StartProcess asynchronously.
Best way, if you ask me, would be to start processing asynchronously, so that you maintain full control of the UI and process at the same time.
http://msdn.microsoft.com/en-us/library/2e08f6yc(v=vs.71).aspx
Try calling that method at the end of the FormLoad event, the control should have finished loading by then. If it hasn't that you may need perform some checks and possibly create a custom event that fires when you're happy that it is ready.
Another solution is to have a button that the user must press to trigger the processing, which they will only be able to click once everything has loaded
EDIT: The reason it look's like it's happening is because you're starting the process in one of the control's load method, which I assume is not the last control to load, so it's starts processing before the other controls are given a chance to load. Make StratProcess method public and call it in the FormLoad method of the parent form instead, like so:
private void ParentForm_Load(object sender, EventArgs e)
{
FeatureRemovalControl.StratProcess(); // Should it be called StartProcess instead?
}
Beware though this is still doing the processing on the UI thread, so the screen may appear to 'hang' whilst this is happening so I advise you move it to a background thread as others have suggested.
I have a button in my program that supposed to be clicked after a while loop finished, whats the code to click the button?
To programatically click a button just call the Click method:
button.Click();
Note that this doesn't cause the UI to update as if the button had been pressed - it just results in the event handler for the click event being run.
In your question you mention that you are running a while loop that presumably takes some time. If you do this in the naive way - running it in the main application thread - it will cause the UI to block while the loop is running. To fix this you need to run the while loop in another thread, for example by using a BackgroundWorker. But then when your loop finishes you have to be careful to ensure that the click event is called back on the main thread. The general way to do this is to use Invoke, but in the specific case that you have a BackgroundWorker you can run the code after the loop finishes in the OnRunWorkerCompleted event handler then you don't need to call Invoke yourself as the BackgroundWorker takes care of this for you.
I have a web application and I'm attempting to put an ajax timer control in it to give me a post back every 10-20 seconds. (possibly longer depending on performance). I have a lot of dynamically created each with auto postback. These controls are inside of their own update panel.
Well, whenever an AJAX timer tick happens, I want to be able to know this at page_load so that I can have some conditions off of this(such as not creating some controls or whatever).
So how can I know at Page_Load time that the reason for the post back was a tick event? I have tried doing something like if(Request.Form[mytimer.UniqueID]!=null) but that is always a false condition(it is always null)
Basically, I just want to know if an AJAX timer tick event will happen, before the event actually occurs(which is after page_load)
I think this is what your looking for:
http://geekswithblogs.net/mahesh/archive/2006/06/27/83264.aspx
The article explains how to figure out which control caused the post back which in your case would be your timer control.