I'm loading third party webpage that contains following code
<script type="text/javascript">
onDomReady(function() { some_code1; });
</script>
into WebBrowser component. After some_code1 had executed I need to do some manipulations with Dom that will make some_code1 invalid. The question is how to determine that some_code1 had executed?
I cant't do
private void web_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
DoRequiredManipulations();
}
Since this event will occur before some_code1 has executed and will make it invalid.
Also I can't do
private void web_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
web.Document.InvokeScript("doSome_code1");
DoRequiredManipulations();
}
Since some_code1 is declared as an anonymous function.
It seems that the only way to do it is this:
private void web_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
var script = GetScriptText(web.DocumentText);
//execute script in webbrowser
DoRequiredManipulations();
}
The problem is that I don't know how to execute this script in webbrowser. I had tried web.Navigate("javascript: " + script); but it doesn't work correctly.
I found how to do that:
HtmlElement scriptEl = web.Document.CreateElement("script");
(scriptEl.DomElement as IHTMLScriptElement).text = "function myscript() { " + script.Text + " }";
web.Document.GetElementsByTagName("head")[0].AppendChild(scriptEl);
web.Document.InvokeScript("myscript");
Related
I have a WebBrowser control:
<phone:WebBrowser Name="ArticleContent" Navigating="ArticleContent_Navigating" Navigated="ArticleContent_Navigated" />
And i get article from server like a HTML string:
string Article = "<p>Sometext</p><span style=\"font-family:"Arial","sans-serif";mso-fareast-font-family:"Arial Unicode MS"; mso-fareast-language:LV\">artjomgsd#inbox.lv</span>";
I do this:
ArticleContent.NavigateToString(Article);
And have this function to stop loading icon:
private void ArticleContent_Navigated(object sender, NavigationEventArgs e)
{
HideLoading();
}
And this function to handle links ( to open links in external browser):
private void ArticleContent_Navigating(object sender, NavigatingEventArgs e)
{
e.Cancel = true;
WebBrowserTask webBrowserTask = new WebBrowserTask();
webBrowserTask.Uri = new Uri(e.Uri.ToString(), UriKind.Absolute);
webBrowserTask.Show();
}
My question is, why when i tap E-mail hyperlink nothing hapens? It even doesn't enter ArticleContent_Navigating() function?
P.S. I want to open MailTask on clicking on mail hyperlink.
Unfortunately, mailto: it not supported by the WebBrowser control on Windows Phone.
What you can do is inject Javascript in the HTML that will enumerate all a tags and wire up an onclick event. That event will call window.external.Notify which will in turn raise the ScriptNotify event of the WebBrowser, with the URL as a parameter.
It is a little complicated but I think it's the only option for dealing with the mailto protocol on Windows Phone.
Here is some sample code:
// Page Constructor
public MainPage()
{
InitializeComponent();
browser.IsScriptEnabled = true;
browser.ScriptNotify += browser_ScriptNotify;
browser.Loaded += browser_Loaded;
}
void browser_Loaded(object sender, RoutedEventArgs e)
{
// Sample HTML code
string html = #"<html><head></head><body><a href='mailto:test#test.com'>Send an email</a></body></html>";
// Script that will call raise the ScriptNotify via window.external.Notify
string notifyJS = #"<script type='text/javascript' language='javascript'>
window.onload = function() {
var links = document.getElementsByTagName('a');
for(var i=0;i<links.length;i++) {
links[i].onclick = function() {
window.external.Notify(this.href);
}
}
}
</script>";
// Inject the Javascript into the head section of the HTML document
html = html.Replace("<head>", string.Format("<head>{0}{1}", Environment.NewLine, notifyJS));
browser.NavigateToString(html);
}
void browser_ScriptNotify(object sender, NotifyEventArgs e)
{
if (!string.IsNullOrEmpty(e.Value))
{
string href = e.Value.ToLower();
if (href.StartsWith("mailto:"))
{
EmailComposeTask email = new EmailComposeTask();
email.To = href.Replace("mailto:", string.Empty);
email.Show();
}
}
}
Problem with your Html tag just write Http// before mailto:artjomgsd#inbox.lv\ on your link it will work fine
like bellow
"<p>Sometext</p><span style=\"font-family:"Arial","sans-serif";mso-fareast-font-family:"Arial Unicode MS"; mso-fareast-language:LV\">artjomgsd#inbox.lv</span>";
i tested this code in my application now its work..
I have a simple C # application that contains buttons and a web browser, each button execute a request and displays the result of the request on the web browser. And use the results of a request in the next button.
private void button1_Click(object sender, EventArgs e)
{
webBrowser1.Navigate("http://www.test.com");
}
private void button2_Click(object sender, EventArgs e)
{
if (webBrowser1.Document.GetElementById("tesxtbox1") != null)
{
HtmlElement txt1 = webBrowser1.Document.GetElementById("tesxtbox1");
txt1.SetAttribute("value", "test");
webBrowser1.Document.Forms[0].InvokeMember("submit");
}
}
Is there any method or way to perform the two buttons with a single click, but the second button, do not execute until the web browser is loaded.
in the first button, I added
webBrowser1.DocumentCompleted + = new WebBrowserDocumentCompletedEventHandler (Button2_Click);
but the second button excuted several times, so I added in the last line of the button 2:
webBrowser1.DocumentCompleted - = new WebBrowserDocumentCompletedEventHandler (Button2_Click);
it works, but in the console I find that Button 2 is execute twice
Thanks in advance!
You shouldn't think like executing second button click. There is DocumentCompleted event which you must listen to and execute neccesary code afterwards.
private void button3_Click(object sender, EventArgs e)
{
webBrowser1.DocumentCompleted += (sender, e) => {button2_Click(sender, e);};
button1_Click(sender, e);
}
will register the button2_Click method to be executed after the document is loaded completely as triggered by button1_Click().
You should add an event that will call the code once the document has completed loading.
private void Form1_Load(object sender, EventArgs e)
{
webBrowser1.DocumentCompleted += webBrowser1_DocumentCompleted;
}
void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
button2_Click(sender, e);
}
You could make the following call from your button1_click method.
button2_Click(sender, e);
You could give an argument in the url:
webBrowser1.Navigate("http://www.test.com?excuteSecondButton=Yes");
Then on the second page you check if that argument was given:
PageLoad()
{
if(Request.QueryString["executeSecondButton"].Equals("Yes"))
{
button2_Click(button2, new RoutedEventArgs());
}
}
I'm using the C# WebBrowswer control and I have a problem that when a button like "Next" is pressed when the page is not loaded yet the program tries to proceed but instead gives me a null error.
Is there is a function to make the program wait until the page has completed loading?
I tried to put a while loop in the program that checks the title of the html page but then the program freezes. Something like will freeze the program:
while(!webbrowser1.Document.Title.ToString().Equals("NextPageTitle"))
{
}
::NextCommands::
It Doesnt work, i tried that and the button "fblqf" is not clicked. but its not returns null error..
public void button1_Click(object sender, EventArgs e)
{
webBrowser1.Document.GetElementById("q").SetAttribute("value", "חחח");
webBrowser1.Document.GetElementById("btnK").InvokeMember("Click");
webBrowser1.DocumentCompleted += webBrowser1_DocumentCompleted;
}
void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
// do the work you need to do now that that page has completed loading
webBrowser1.Document.GetElementById("fblqf").InvokeMember("Click");
}
Solution:
public void button1_Click(object sender, EventArgs e)
{
webBrowser1.Document.GetElementById("q").SetAttribute("value", "חחח");
webBrowser1.Document.GetElementById("btnK").InvokeMember("Click");
int x=0;
while (x==0)
{
System.Windows.Forms.Application.DoEvents();
if(webBrowser1.Document.GetElementById("pnnext") != null)
break;
}
webBrowser1.Document.GetElementById("pnnext").InvokeMember("Click");
webBrowser1.Document.GetElementById("q").Focus();
}
You need to hook the WebBrowswer.DocumentCompleted event:
Perhaps in your constructor or your OnLoad:
webBrowser1.Document.GetElementById("q").SetAttribute("value", "חחח");
webBrowser1.DocumentCompleted += webBrowser1_DocumentCompleted;
webBrowser1.Document.GetElementById("btnK").InvokeMember("Click");
Then you event looks like this:
void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
// do the work you need to do now that that page has completed loading
}
I Found an easy Solution!!!
public void button1_Click(object sender, EventArgs e)
{
webBrowser1.Document.GetElementById("q").SetAttribute("value", "חחח");
webBrowser1.Document.GetElementById("btnK").InvokeMember("Click");
while (true)
{
System.Windows.Forms.Application.DoEvents();
if(webBrowser1.Document.GetElementById("pnnext") != null)
break;
}
webBrowser1.Document.GetElementById("pnnext").InvokeMember("Click");
webBrowser1.Document.GetElementById("q").Focus();
}
I used the below manner to run a JavaScript upon postback and it worked fine for me.
protected void Page_Load(object sender, EventArgs e)
{
if (this.IsPostBack)
{
Page.ClientScript.RegisterStartupScript(this.GetType(),"PostbackKey","<script type='text/javascript'>document.getElementById('apDiv1').style.visibility = 'hidden';</script>");
Page.ClientScript.RegisterStartupScript(this.GetType(),"PostbackKey","<script type='text/javascript'>function show()</script>");
}
else
{
Page.ClientScript.RegisterStartupScript(this.GetType(),"PostbackKey","<script type='text/javascript'>document.getElementById('apDiv1').style.visibility = 'visible';</script>");
}
}
The above code worked fine and now I want to try something like below.
protected void Page_Load(object sender, EventArgs e)
{
if (this.IsPostBack)
{
Page.ClientScript.RegisterStartupScript(this.GetType(),"verify","<script type='text/javascript'>verify1();</script>");
}
else
{
}
}
in the above code verify1() is a JavaScript linked externally to ASPX page. I am unable to execute verify1() function using this code. And verify1() function works fine when placed as <body onload="verify1();"> Is there any syntax error(s) in my above code?
this may help you,
Page.ClientScript.RegisterStartupScript(this.GetType(), "verify", "verify1()", true);
Maybe that script is being executed before verify1()'s function definition. By the time body.onload fires, the main page has completed parsing and all external scripts have been loaded, which is why it works in that scenario.
Can you use jquery? One option is to use jQuery's onload functionality, which won't be executed until everything is intialized:
$( function() { ...my startup code... });
I am a starter with c# programming language. I placed a simple web browser into a window form. I assign a url address to the browser and I want to see if the browser successfully opened the link I provided.
I know that there is a eventhandler called
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
however, after assigning the url for the browser, I want to write something like
if (webBrowser1_DocumentCompleted)
{
//my code here
}
is this possible? I know you can use "WebBrowserReadyState" but I would prefer to try and use Document ready.
I'm not sure if this is what you are looking for but this is what I would try:
first create an Event Handler in the Constructor of your form class:
public void Form1()
{
webBrowser1.DocumentCompleted +=
new WebBrowserDocumentCompletedEventHandler(WebDocumentCompleted);
}
After this you need to create a method that will be called when that event is fired:
void WebDocumentcompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
//Your code here
}
Hope this helps!
Because loading and rendering of the webpage is running asynchronously you have to do you logic (which should run after the document is loaded) in the event method. You can subscribe the event in this way:
webBrowser.DocumentCompleted += webBrowser_DocumentCompleted;
You have to have a method in your class with this signature in which you can make the coding you want:
void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
// Do something after the document is loaded.
}
You can inspect the result from DownloadDataCompletedEventArgs (e)
class Program
{
static void Main(string[] args)
{
WebClient wb = new WebClient();
wb.DownloadDataAsync("www.hotmail.com");
wb.DownloadDataCompleted += new DownloadDataCompletedEventHandler(wb_DownloadDataCompleted);
}
static void wb_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
{
if (e.Cancelled)//cancelled download by someone/may be you
{
//add necessary logic here
}
else if (e.Error)// all exception can be collected here including invalid download uri
{
//add necessary logic here
}
else if (e.UserState)// get user state for asyn
{
//add necessary logic here
}
else
{
//you can assume here that you have result from the download.
}
}
}