Gecko WebBrowser.DocumentComplete Event - c#

I'm creating an application that contains "geckoWebBrowser" in c #. But I have to wait the complete loading a web page, and then continue to execute other instructions. there is something similar to geckowebbrowser1.DocumentComplete, but i don't know how to use this.
Please help me with my code:
geckoWebBrowser1.Navigate(textBox1.Text);
// i want to perform below thing after web page load completes
listBox1.Items.RemoveAt(listBox1.SelectedIndex);
listBox1.SelectedIndex = 0;
int i = listBox1.Items.Count;
string str = Convert.ToString(i);
label2.Text = str;

You could use event:
geckoWebBrowser1_OnDocumentCompleted(EventArgs e)
But remember this event can fire many times before same page ends loading... write the logic accordingly.

Related

How to execute a method with a button click

How can I add a function to a button that will run a method I've created. I want to write out an array into a message dialog box with a press of a button, but I don't seem to be getting anywhere so i turned to stackoverflow for some help, since googling didn't really help me with my problem.
static void Tractors(Tractor[] tractors)
{
for (int i = 0; i < tractors.Length; i++)
{
Console.WriteLine((i + 1) + ", " + tractors[i].ToString());
}
}
This is my function that writes out the table of "Tractors".
private void button1_Click(object sender, EventArgs e)
{
}
What should I write into the button1_click method so that it would work?
You need to bind the event handler with the button control and write the logic inside this event handler. If its windows form application you can do like this.
this.button1 = new System.Windows.Forms.Button();
this.button1.Click += new System.EventHandler(this.button1_Click);
private void button1_Click(object sender, EventArgs e)
{
//Call your methods here
}
You would call Tractor() the exactly same way you call Console.WriteLine(). Both are static functions.
However the function is utterly messed up and propably not salvageable. The proper name would be printTractorsToConsole(). As it contains the Console.WriteLine() call, it is strongly tied to Console Applications - avoid tying functions to one Display Technology like that.
You need a more general function that creates and returns a string. You can then send that string to WriteLine(), assign it to Label.Text or wherever else you want the string to be. Strings primarily exist for intput from or output towards the user - and there is too many ways to get it to them.
//Not tested against a compiler, may contain syntax errors
static string TractorArrayToString(Tractor[] tractors){
string output = "";
for (int i = 0; i < tractors.Length; i++)
{
output += (i + 1) + ", " + tractors[i].ToString()) + Environment.NewLine;
}
return output;
}
But even function might be a bad idea, as that function would tie all representations to a single format. Generally you would write that loop directly into the Click Event. But this function looks like it is for printing for debug purposes, so it might work.

How do I know when a website finished loaded into WebBrowser?

First i have this button click event:
private void toolStripButton3_Click(object sender, EventArgs e)
{
GetHtmls();
}
Then the method GetHtmls:
private void GetHtmls()
{
for (int i = 1; i < 2; i++)
{
adrBarTextBox.Text = sourceUrl + i;
getCurrentBrowser().Navigate(adrBarTextBox.Text);
targetHtmls = (combinedHtmlsDir + "\\Html" + i + ".txt");
}
}
Now the loop is for one html but later i will change the loop to be i < 45
getCurrentBrowser method:
private WebBrowser getCurrentBrowser()
{
return (WebBrowser)browserTabControl.SelectedTab.Controls[0];
}
Then in the load form1 event I have:
browser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(Form1_DocumentCompleted);
And the completed event:
private void Form1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
WebBrowser currentBrowser = getCurrentBrowser();
StreamWriter writer = File.CreateText(targetHtmls);
writer.Write(getCurrentBrowser().DocumentText);
writer.Close();
}
What I'm doing here is loading the html to the web browser and create a file on the hard disk of the html source content.
But i'm getting two problems:
In the completed event it keep calling the completed event and create the html file over and over again untill the codument is loaded. How can i make that it will do it once in the completed event ? I mean that it will wait untill the dosument loaded and then write to the file and create the file only once ?
How do I make it all when the loop will be i < 45 and not 2?
So it will wait for the first html to be loaded then write to the file when finish the writing make the next html in the loop then write again in the completed event and so on so it will not move on each other one.
The completed event of the web browser document doesn't act like other completed events it keep calling the completed event every second or so until it finish loading the html.
I am not sure what the purpose of the WebBrowser is in this case. That control is for human interaction, not loading X number of sites.
I would recommand to use HttpWebRequest or the newer WebClient class. This is much easier to use in the case you show here.
The WebClient class can be used like this:
WebClient wc = new WebClient();
string html = wc.DownloadString("yourUrl");
This will wait until the request is completed and the result is returned. No need for event handlers or such. You could improve the performance by using async though.

Winform WebBrowser Pass Cookie Then Process Links?

I asked this question a while ago but seems that there are no answers, so i tried to go with an alternative solution but i am stuck now, please see the following code:
WebBrowser objWebBrowser = new WebBrowser();
objWebBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(objWebBrowser_DocumentCompleted);
objWebBrowser.Navigate("http://www.website.com/login.php?user=xxx&pass=xxx");
objWebBrowser.Navigate("http://www.website.com/page.php?link=url");
And here is the event code:
WebBrowser objWebBrowser = (WebBrowser)sender;
String data = new StreamReader(objWebBrowser.DocumentStream).ReadToEnd();
Since it's impossible for me to use the WebBrowser.Document.Cookies before a document is loaded, i have first to navigate the login page, that will store a cookie automatically, but after that i want to call the other navigate in order to get a result. Now using the above code it doesn't work cause it always takes the second one, and it won't work for me to put it in the event cause what i want is like this:
Navigate with the login page and store cookie for one time only.
Pass a different url each time i want to get some results.
Can anybody give a solution ?
Edit:
Maybe the sample of code i provided was misleading, what i want is:
foreach(url in urls)
{
Webborwser1.Navigate(url);
//Then wait for the above to complete and get the result from the event, then continue
}
I think you want to simulate a blocking call to Navigate if you are not authorized. There are probably many ways to accomplish this and other approaches to get what you want, but here's some code I wrote up quickly that might help you get started.
If you have any questions about what I'm trying to do here, let me know. I admit it feels like "a hack" which makes me think there's a smarter solution, but anyway....
bool authorized = false;
bool navigated;
WebBrowser objWebBrowser = new WebBrowser();
void GetResults(string url)
{
if(!authorized)
{
NavigateAndBlockWithSpinLock("http://www.website.com/login.php?user=xxx&pass=xxx");
authorized = true;
}
objWebBrowser.Navigate(url);
}
void NavigateAndBlockWithSpinLock(string url)
{
navigated = false;
objWebBrowser.DocumentCompleted += NavigateDone;
objWebBrowser.Navigate(url);
int count = 0;
while(!navigated && count++ < 10)
Thread.Sleep(1000);
objWebBrowser.DocumentCompleted -= NavigateDone;
if(!navigated)
throw new Exception("fail");
}
void NavigateDone(object sender, WebBrowserDocumentCompletedEventArgs e)
{
navigated = true;
}
void objWebBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if(authorized)
{
WebBrowser objWebBrowser = (WebBrowser)sender;
String data = new StreamReader(objWebBrowser.DocumentStream).ReadToEnd();
}
}

Web scraping - can't get a table present in the webpage

I'm parsing the HTML of a webpage for getting some information. In my webpage, I have a <table> which I'm trying to access. But when I write the following code, 0 elements are returned:
WebBrowser csexBrowser = new WebBrowser();
HtmlElementCollection table2 = this.csexBrowser.Document.GetElementsByTagName("table");
Here, table2 has nothing. 0 elements.I'm using winforms.
EDIT: This is the link. If you search for a name, then it will show you some results in a table.
There is a verification step which precedes access to the link you provided. In the http://www.nsopw.gov/en-US/Search/Verification document, there are no tables.
Are you sure you pass the verification URL first?
[EDIT]
Please try this:
public Form1()
{
InitializeComponent();
WebBrowser csexBrowser = new WebBrowser();
//here we say what we want to do when the Navigated event occurs
csexBrowser.Navigated += csexBrowser_Navigated;
//this takes some time
csexBrowser.Navigate("http://www.nsopw.gov/en-US/Search");
}
void csexBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
//here the document is loaded and we will find the table
HtmlElementCollection table2 = ((WebBrowser)sender).Document.GetElementsByTagName("table");
}
If you insist on navigating with a browser then you must wait for the navigation to finish. Personally I hate this method plus the event fire most people go for can multi-trigger I have found.
Do this:
csexBrowser.Navigate(Url);
while (csexBrowser.ReadyState != WebBrowserReadyState.Complete)
{
Application.DoEvents();
}
Simply navigates to the given url and doesn't continue until the page has finished loading.
Done and done.

How to make WebBrowser wait till it loads fully?

I have a C# form with a web browser control on it.
I am trying to visit different websites in a loop.
However, I can not control URL address to load into my form web browser element.
This is the function I am using for navigating through URL addresses:
public String WebNavigateBrowser(String urlString, WebBrowser wb)
{
string data = "";
wb.Navigate(urlString);
while (wb.ReadyState != WebBrowserReadyState.Complete)
{
Application.DoEvents();
}
data = wb.DocumentText;
return data;
}
How can I make my loop wait until it fully loads?
My loop is something like this:
foreach (string urlAddresses in urls)
{
WebNavigateBrowser(urlAddresses, webBrowser1);
// I need to add a code to make webbrowser in Form to wait till it loads
}
Add This to your code:
webBrowser1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted);
Fill in this function
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) {
//This line is so you only do the event once
if (e.Url != webBrowser1.Url)
return;
//do you actual code
}
After some time of anger of the crappy IE functionality I've came across making something which is the most accurate way to judge page loaded complete.
Never use the WebBrowserDocumentCompletedEventHandler event
use WebBrowserProgressChangedEventHandler with some modifections seen below.
//"ie" is our web browser object
ie.ProgressChanged += new WebBrowserProgressChangedEventHandler(_ie);
private void _ie(object sender, WebBrowserProgressChangedEventArgs e)
{
int max = (int)Math.Max(e.MaximumProgress, e.CurrentProgress);
int min = (int)Math.Min(e.MaximumProgress, e.CurrentProgress);
if (min.Equals(max))
{
//Run your code here when page is actually 100% complete
}
}
Simple genius method of going about this, I found this question googling "How to sleep web browser or put to pause"
According to MSDN (contains sample source) you can use the DocumentCompleted event for that. Additional very helpful information and source that shows how to differentiate between event invocations can be found here.
what you experiencend happened to me . readyStete.complete doesnt work in some cases. here i used bool in document_completed to check state
button1_click(){
//go site1
wb.Navigate("site1.com");
//wait for documentCompleted before continue to execute any further
waitWebBrowserToComplete(wb);
// set some values in html page
wb.Document.GetElementById("input1").SetAttribute("Value", "hello");
// then click submit. (submit does navigation)
wb.Document.GetElementById("formid").InvokeMember("submit");
// then wait for doc complete
waitWebBrowserToComplete(wb);
var processedHtml = wb.Document.GetElementsByTagName("HTML")[0].OuterHtml;
var rawHtml = wb.DocumentText;
}
// helpers
//instead of checking readState . we get state from DocumentCompleted Event via bool value
bool webbrowserDocumentCompleted = false;
public static void waitWebBrowserToComplete(WebBrowser wb)
{
while (!webbrowserDocumentCompleted )
Application.DoEvents();
webbrowserDocumentCompleted = false;
}
form_load(){
wb.DocumentCompleted += (o, e) => {
webbrowserDocumentCompleted = true;
};
}

Categories

Resources