phone:WebBrowser handle mail link - c#

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..

Related

c# Get URL of the new page after invoking click in Web Browser

I have to navigate through some pages with an Application Console in C#, I have a known URL as a starting page, but other URLs are not known, I reach them by clicking on buttons in the starting page.
This is the code of the button I need to click on the page:
<input name="ctl00$ContentPlaceHolder1$btn_invia" type="button" id="myId" onclick="ReDirect();" class="myClass" value="BUTTON TEXT" />
I tried this code to navigate to the start page, and it works:
class Program
{
private static WebBrowser wb1 = new WebBrowser();
[STAThread]
static void Main(string[] args)
{
runBrowserThread(new Uri("http://www.myUrl.com"));
}
private static void runBrowserThread(Uri url)
{
var th = new Thread(() => {
var br = new WebBrowser();
br.DocumentCompleted += Br_DocumentCompleted; ;
br.Navigate(url);
Application.Run();
});
th.SetApartmentState(ApartmentState.STA);
th.Start();
}
private static void Br_DocumentCompleted(object sender,
WebBrowserDocumentCompletedEventArgs e)
{
//Retrieve string content of document
var document = ((WebBrowser)sender).Document;
var documentAsIHtmlDocument3 =
(mshtml.IHTMLDocument3)document.DomDocument;
var content = documentAsIHtmlDocument3.documentElement.innerHTML;
//Parse content with html agility pack or whatever
//Click on button
wb1.Document.GetElementById("myId").InvokeMember("click");
Application.ExitThread();
}
}
When I click on the button, it loads a new page.
But when I call .InvokeMember("click"); it freezes, how can I make the WebBrowser wb1 go to the new page?
I figured out where I was wrong, I called wb1.Document.GetElementById("myId").InvokeMember("click"); but wb1 wasn't initalized, so I didn't call .InvokeMember("click") on an existing element. I modified in this way:
((WebBrowser)sender).Document.GetElementById("myId").InvokeMember("Click");
in the Br_DocumentCompleted method, and now it works. But now I have another problem: I modified the Br_DocumentCompleted method in this way, because I have to click on a button in the new page, to open a third page:
private static void Br_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
//Retrieve string content of document
var document = ((WebBrowser)sender).Document;
var documentAsIHtmlDocument3 = (mshtml.IHTMLDocument3)document.DomDocument;
var content = documentAsIHtmlDocument3.documentElement.innerHTML;
if (((WebBrowser)sender).Url.AbsoluteUri.Contains("startpage.aspx"))
{
//Click on button
((WebBrowser)sender).ScriptErrorsSuppressed = true;
((WebBrowser)sender).Document.GetElementById("myId").InvokeMember("Click");
}
else if (((WebBrowser)sender).Url.AbsoluteUri.Contains("page1.aspx"))
{
((WebBrowser)sender).Document.GetElementById("btn_send").InvokeMember("Click");
}
else if (((WebBrowser)sender).Url.AbsoluteUri.Contains("page2.aspx"))
{
//Some code
Application.ExitThread();
}
}
And the "btn_send" on the page1 has this code:
<input onclick="openEVERFANCY('#CChildren','N'); return false;" id=btn_send class=buttonVerifyDisp type=button value=GO>
and when I call ((WebBrowser)sender).Document.GetElementById("btn_send").InvokeMember("Click"); on this button, it doesn't go to the third page, even if I have the DocumentCompleted event handler

Get final HTML content after javascript finished by Open Webkit Sharp

I'm writing a software that gets the content from URL. When working on that, I run into to problem that I can not get exactly the HTML content after the java script finished.
There are some websites that renders HTML by java-script, some do not support browsers which does not run js.
I tried using System.Windows.Controls.WebBrowser with WebBrowser.Document in LoadCompleted but no luck.
After that, I tried the OpenWebkitSharp library. On the UI, it showes the content of website correctly, but with code Document in DocumentCompleted, it still returns the content which does not rendered by java-script.
Here is my code:
...
using WebKit;
using WebKit.Interop;
public MainWindow()
{
windowFormHost = new System.Windows.Forms.Integration.WindowsFormsHost();
webBrowser = new WebKit.WebKitBrowser();
webBrowser.AllowDownloads = false;
windowFormHost.Child = webBrowser;
grdBrowserHost.Children.Add(windowFormHost);
webBrowser.Load += WebBrowser_Load;
}
private void WebBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
var contentHtml = ((WebKitBrowser)sender).DocumentAsHTMLDocument;
}
The contentHtml has value which is not rendered after java-script finished.
Do solve this problem, I have added some trick into my code to get the full Html content after java-script finished.
using WebKit;
using WebKit.Interop;
using WebKit.JSCore; //We need add refrence JSCore which following with Webkit package.
public MainWindow()
{
InitializeComponent();
InitBrowser();
}
private void InitBrowser()
{
windowFormHost = new System.Windows.Forms.Integration.WindowsFormsHost();
webBrowser = new WebKit.WebKitBrowser();
webBrowser.AllowDownloads = false;
windowFormHost.Child = webBrowser;
grdBrowserHost.Children.Add(windowFormHost);
webBrowser.Load += WebBrowser_Load;
}
private void WebBrowser_Load(object sender, EventArgs e)
{
//The ResourceIntercepter will throws exception if webBrowser have not finished loading its components
//We can not use DocumentCompleted to load the Htmlcontent. Because that event will be fired before Java-script is finised
webBrowser.ResourceIntercepter.ResourceFinishedLoadingEvent += new ResourceFinishedLoadingHandler(ResourceIntercepter_ResourceFinishedLoadingEvent);
}
private void ResourceIntercepter_ResourceFinishedLoadingEvent(object sender, WebKitResourcesEventArgs e)
{
//The WebBrowser.Document still show the html without java-script.
//The trict is call Javascript (I used Jquery) to get the content of HTML
JSValue documentContent = null;
var readyState = webBrowser.GetScriptManager.EvaluateScript("document.readyState");
if (readyState != null && readyState.ToString().Equals("complete"))
{
documentContent = webBrowser.GetScriptManager.EvaluateScript("$('html').html();");
var contentHtml = documentContent.ToString();
}
}
Hope this one can help you.

How do you click a button in a webbrowser control?

For example, using code and no user input, how would I have my program click the "Search" button on google (assuming I've already filled in the search box and am at google.com)
webBrowser1.Navigate("http://www.google.com");
If you have an ID use this:
webBrowser1.Document.GetElementById("id").InvokeMember("click");
If you have TagName use this
webBrowser1.Navigate("http://www.google.com");
In Web Browser DocumentCompleted event
HtmlElement textElement = webBrowser1.Document.All.GetElementsByName("q")[0];
textElement.SetAttribute("value", "your text to search");
HtmlElement btnElement = webBrowser1.Document.All.GetElementsByName("btnG")[0];
btnElement.InvokeMember("click");
If you have name Class use this:
HtmlElementCollection classButton = webBrowser1.Document.All;
foreach (HtmlElement element in classButton)
{
if (element.GetAttribute("className") == "button")
{
element.InvokeMember("click");
}
}
For adding text in a TextBox to search google.com, use this:
webBrowser1.Document.GetElementById("gs_tti0").InnerText = "hello world";
Try the following code:
public WebBrowser webBrowser1 = new WebBrowser();
private void WebForm_Load(object sender, EventArgs e)
{
try
{
webBrowser1.Height = 1000;
webBrowser1.Width = 1000;
this.Controls.Add(webBrowser1);
webBrowser1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(WebBrowser_DocumentCompleted);
this.webBrowser1.Navigate("www.google.com.au");
}
catch
{ }
Write down the following function in your c# form:
public void WebBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
var webBrowser = sender as WebBrowser;
webBrowser.DocumentCompleted -= WebBrowser_DocumentCompleted;
HtmlElement textElement = webBrowser.Document.All.GetElementsByName("q")[0];
textElement.SetAttribute("value", "mlm company");
HtmlElement btnElement = webBrowser.Document.All.GetElementsByName("btnG")[0];
btnElement.InvokeMember("click");
}
In addition to using InvokeMember and others, if your web page has issues responding when called by ID or Class, you can try using {TAB} & {ENTER} using the SendKeys class within .NET. I've written a lot of scripts for web pages and have found that I've had to use a combination of both (even though SendKeys is far messier than the methods in #AleWin's answer).
Here is the link to the SendKeys class.

Getting the HTML content of the current page with databound controls

I'm trying to create a control that converts the page it's on into a PDF.
protected void ConvertPageToPDF_click(object sender, EventArgs e)
{
string pageHtml;
byte[] pdfBytes;
string url = HttpContext.Current.Request.Url.AbsoluteUri;
// get the HTML for the entire page into pageHtml
HtmlTextWriter hw = new HtmlTextWriter(new StringWriter());
this.Page.RenderControl(hw);
pageHtml = hw.InnerWriter.ToString();
// send pageHtml to a library for conversion
// send the PDF to the user
}
This partially works. On my pages I have several repeaters; their content does not show up in pageHtml. Any thoughts on why that is? How should I fix this?
It turns out that I had to render the control after the data had been bound to it. My click method just adds an event handler:
protected void ConvertRepeaterToPDF_click(object sender, EventArgs e)
{
// handle the PreRender complete method
Page.PreRenderComplete += new EventHandler(Page_OnPreRenderComplete);
}
Then in Page_OnPreRenderComplete I can use RenderControl as above.

DocumentCompleted

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.
}
}
}

Categories