I've got the WebBrowser control to open links in my default browser like this:
private void webBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e)
{
if (e.Url.ToString() != "about:blank")
{
e.Cancel = true;
System.Diagnostics.Process.Start(e.Url.ToString());
}
}
This works great but if I load a document that contains some IFrame elements those will be opened in the system browser as well (mostly embedded stuff, like Google Maps, Digg icons, etc..).
How do I keep iframes loading in the Webbrowser control and user clicked links in the system browser?
I've come to the conclusion that the .NET WebBrowser component is almost useless in this regard. I've tried to read WebBrowserNavigatingEventArgs.TargetFrameName but it will return the name attribute of the iframe element only if the HTML document has it. Otherwise it will spit out an empty "" string. Returning null on non-frame links would have been tons more useful.
So the only fix I've found for this is using the AxWebBrowser control, and specifically listening to the BeforeNavigate2 event. I haven't tested as much as I should have, but it appears that the "flags" property in DWebBrowserEvents2_BeforeNavigate2Event is set to 64 each time it's user triggered.
private void axWebBrowser1_BeforeNavigate2(object sender, AxSHDocVw.DWebBrowserEvents2_BeforeNavigate2Event e)
{
// 64 means user triggered
if ((int)e.flags == 64 && e.uRL.ToString() != "about:blank")
{
e.cancel = true;
System.Diagnostics.Process.Start(e.uRL.ToString());
}
}
MSDN docs says that flags is an IE7+ only parameter, so I have no idea what happens on IE6 machines...
Using Internet Explorer from .NET has some really valuable information regarding AxWebBrowser.
Related
I have a main form that opens a new form that contains a web browser control that navigates to the entered url when it is loaded. I've tried different things I've found and this is my latest code: I have a function (GoToURL) that is triggered at the Shown event of the form which is here:
public delegate void Launch();
private void launchBrowser()
{
webBrowser1.Navigate(GlobalData.URL);
}
private void GoToURL(object sender, EventArgs e)
{
webBrowser1.Invoke(new Launch(launchBrowser));
}
I have nothing in the Document Completed function:
void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
}
The web browser control loads the url just fine and I can scroll around in it, but on some links or buttons the control goes white and nothing happens. It won't proceed with the desired function. A more specific example is I am logging into a site and once I click the submit button it just hangs there. A "loading" image is presented and it just sits there. I know the Document Completed function above is triggered when this happens, too.
I apologize for my inexperience with C# and this is the first time using the web browser control (forms not wpf), so I am at a loss of what to try. I suspect its a threading issue, but that's as far as I got.
You are experiencing issues within the browser itself. Please launch IE and test the same there. I suspect you'll see the same issues.
Your experience is tied to the version of Internet Explorer you have in your system, and javascript errors have been frequents in the earlier versions of IE. Upgrade to IE11 in any case.
If that's not an option, try using a browser control with a different rendering engine. I'm too lazy to find and list the options, but I've used a few and they work well.
to avoid JavaScript Errors please follow this
public frmMain()
{
//Java Script Error popup block
webBrowser1.ScriptErrorsSuppressed = true;
}
Please Check this on loading Uri using
webBrowser1.Url = new Uri(Url.Trim().ToString());
Url - your desired Url
I know this has been discussed several times around here but the default behaviour for opening links
clicked in a WebBrowser control does not work for my application.
So while this works as in it opens a link clicked in IE:
private void webBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e)
{
System.Diagnostics.Process.Start(e.Url.ToString());
e.Cancel = true;
}
I am using a dropdown list to update the html file that the webBrowser is displaying like so:
private void ddl_SelectedIndexChanged(object sender, EventArgs e)
{
webBrowser1.Url = myURI;
}
Now the problem I'm having is that with the _Navigating method above, the webBrowser does not load any subsequent changes to the URL (thanks to the e.cancel I guess) so it only displays the first html file it loads.
If I remove the _Navigating method it updates fine but then the links open up in the same webBrowser control which is what I do not want.
How can I get it to work both ways?
I hope this can help you.
If you want to open a link in a browser, you can add this simple code:
Process.Start("http://google.com");
Remember, there is a lot of information about it. Here in stack Overflow you can take a look in this post: How to open in default browser in C#
If you want to open your link in another browser, you can use this code:
System.Diagnostics.Process.Start("firefox.exe", "http://www.google.com");
Don't forget to visit this post called: How do I open alternative webbrowser (Mozilla or Firefox) and show the specific url?
And Finally, I could recommend you this stack overtflow post called: .NET C#: WebBrowser control Navigate() does not load targeted URL
I hope this information can help you a little bit.
This is an old post but I believe I may understand what the original poster wanted to do. They wanted a page to load in the webbrowser control if the user selected it from the dropdown list but any links in the loaded page should open in the user's web browser. If this is indeed the case, the original poster need a flag on the form to determine the behavior.
The original poster simply needed a flag such as linksOpenInSystemBrowser shown below.
using System;
using System.Windows.Forms;
namespace Browser_Test
{
public partial class myForm : Form
{
private bool linksOpenInSystemBrowser = false;
public myForm()
{
InitializeComponent();
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
linksOpenInSystemBrowser = false;
webBrowser1.Navigate(comboBox1.SelectedItem.ToString());
}
private void webBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e)
{
if(!linksOpenInSystemBrowser)
{
linksOpenInSystemBrowser = true;
return;
}
System.Diagnostics.Process.Start(e.Url.ToString());
e.Cancel = true;
}
}
}
Okay, the goal is to attempt to detect when a web page has been updated, and display the updated page in a WebBrowser control. For instance, say that I know Amazon will make the Playstation 4 available today, but I don't know when. I put the address of the Amazon PS4 page in my form, and the program periodically launches a WebBrowser to that page and saves the HTML to a list of string. Next time around when it launches the browser, it will check the results against my list. If the list already contains this particular string, the WebBrowser is closed and we wait again using Thread.Sleep.
private void Launch()
{
while (blnWorking)
{
if (intWindowCount < intMaxCount)
{
ShowBrowserUri(GetBrowserUri());
}
if (intWait > 0)
Thread.Sleep(intWait);
}
}
delegate void ShowBrowserUriDelegate(Uri uri);
private void ShowBrowserUri(Uri uri)
{
if (InvokeRequired)
{
ShowBrowserUriDelegate del = new ShowBrowserUriDelegate(ShowBrowserUri);
Invoke(del, uri);
}
else
{
CookieContainer cc = GetUriCookieContainer(uri);
CookieCollection cc1 = new CookieCollection();
if (cc != null)
{
cc1 = cc.GetCookies(uri);
}
THBrowser thb = new THBrowser(uri, cc1, this); //THBrowser is a form with a WebBrowser control
//THBrowser calls the Navigate method of its WebBrowser control
intWindowCount++;
thb.Show();
thb.SendToBack();
}
}
The problem is, my program seems to be randomly opening the website in Firefox (my default browser) instead of using the THBrowser/WebBrowser. I've stepped through, and it seems to occur every time I step out of the Thread.Sleep.
It also may be relevant that OnDocumentComplete for my WebBrowser compares the current HTML to my List of HTML strings and closes the control if the page contents are already contained in my list.
I don't have the most recent version in front of me, but that part goes something like...
void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if (e.Url.AbsolutePath != (sender as WebBrowser).Url.AbsolutePath)
return;
if (ResultsList.Contains(this.webBrowser1.Document.Body.InnerHtml)
this.Close();
else
ResultsList.Add(this.webBrowser1.Document.Body.InnerHtml);
}
I think this may be relevant because the THBrowser opens briefly, disappears, then a new tab is immediately opened in Firefox.
I'm pretty sure the Thread.Sleep has something to do with it. Although, I had seen this problem occasionally before introducing the Thread.Sleep, it has multiplied 100 fold since.
Maybe Thread.Sleep isn't the best way to space out my intervals. Maybe I'm just going about this completely wrong. Any suggestions are appreciated.
First, it's highly unlikely that Thread.Sleep has anything to do with the page sometimes loading in Firefox rather than in the WebBrowser control.
Thread.Sleep is not typically the best way to do things periodically. You'd probably be better off with a timer. If you're using Windows Forms, that's System.Windows.Forms.Timer. Set the Interval to whatever delay you want, and have the Tick event update the browser.
I'm not sure why you're creating a new WebBrowser control every time. Seems you'd be better off creating it just once and then calling Refresh method.
Finally, do you really need a WebBrowser? You might be better off just using WebClient.DownloadString to download the HTML.
I am currently working on an app for WP7 for my university, and need a temporary solution to a problem. Now this solution is, that I will be loading a webpage using the web browser control for WP7. For example: http://m.iastate.edu/laundry/
Now as you see on the webpage, there are certain elements I want to hide, for example the back button. For now, what I have done to handle the back button is something like this:
private void webBrowser1_Navigating(object sender, NavigatingEventArgs e)
{
// Handle loading animations
// Handle what happens when the "back" button is pressed
Uri home = new Uri("http://m.iastate.edu/");
// The the current loading address is home
// Cancel the navigation, and go back to the
// apps home page.
if (e.Uri.Equals(home))
{
e.Cancel = true;
NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));
}
}
Now that works beautifully, except for the part that there is a back button on the hardware.
So my second option is to completely hide the back button ONLY on that page, and not its children. So not on http://m.iastate.edu/laundry/l/0
I am still debating on just parsing the data and displaying it in my own style, but I'm not sure if that's completely needed seeing how the data needs constant internet service and is already in a well-put format. Plus, I feel like that would be a waste of resources? Throw in your opinions on that too :)
Thanks!
You should inject a script in the page with InvokeScript.
Here is the kind of Javascript code you need to remove the back button:
// get the first child element of the header
var backButton = document.getElementsByTagName("header")[0].firstChild;
// check if it looks like a back button
if(backButton && backButton.innerText == "Back") {
// it looks like a back button, remove it
document.getElementsByTagName("header")[0].removeChild[backButton];
}
Call this script with InvokeScript:
webBrowser1.InvokeScript("eval", "(function() { "+ script +"}()");
Warning: IsScriptEnabled must be set to true on the web control
If the removal of the back button depends of the page, just test the navigating URI in C# and inject the script if neeeded.
I'm trying to master the WebBrowser control for use in a data extraction application I'm building.
One of the requirements here is to be able to record user actions and play them back. While I'm having a little success, I'm confused about whether I'm going about this in the right way.
There seem to be code samples over the web that use the control in very different ways. Not to mention that there is a WinForms implementation, a WPF implementaion and a Silverlight implementation.
Can someone confirm:
Am I right in my findings so far that the WPF version of the control does not have the same functionality as the WinForms version - and is somewhat limited in terms of reacting to some events?
Why would someone choose to use the mshtml based classes when using the control, when it seems that in WinForms at least, equivalent means of performing the same task exist in the Windows Forms classes?
Examples
Winforms Click Event Handle
void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
foreach (HtmlElement ele in uc_webBrowser.Document.All)
{
HtmlElementEventHandler eventhandler = new HtmlElementEventHandler(documentClickHandler);
if (ele.TagName.ToLower() == "a" || ele.TagName.ToLower() == "input" || ele.TagName.ToLower() == "select" || ele.TagName.ToLower() == "img")
{
ele.Click -= eventhandler;
ele.Click += eventhandler;
}
}
}
Click event handle using mshtml classes
void webBrowser1_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
// Add doc null check otherwise the event handlers are assigned multiple times
// http://stackoverflow.com/questions/5400020/how-come-htmldocumentevent-onclick-fires-up-multiple-times
if (doc == null)
{
var eventHdlr = new mshtml.HTMLDocumentEvents2_onclickEventHandler(ClickEventHandler);
doc = (mshtml.HTMLDocument)webBrowser1.Document.DomDocument;
mshtml.HTMLDocumentEvents2_Event iEvent = (mshtml.HTMLDocumentEvents2_Event)doc;
iEvent.onclick -= eventHdlr;
iEvent.onclick += eventHdlr;
//iEvent.oncellchange += new HTMLDocumentEvents2_oncellchangeEventHandler(iEvent_oncellchange);
//iEvent.oncontrolselect += new HTMLDocumentEvents2_oncontrolselectEventHandler(iEvent_oncontrolselect);
//iEvent.onselectionchange += new HTMLDocumentEvents2_onselectionchangeEventHandler(iEvent_onselectionchange);
}
}
Years ago I implemented a somewhat complex WYSIWYG editor using WinForms' WebBrowser, back then the browser was IE 7 (there was that or Firefox 1 or 2, I don't remember). If you go any further than loading a page in the browser, you will see that the MSHTML PIA is a pain to work with.
The behaviour of the browser component wasn't 100% deterministic with IE 7 (hopefully that may have changed with IE 9, but worse yet, you may have to deal with different versions of the Microsoft browser). However a well designed OO layer above all that will make miracles for your productivity.
I will try to answer your doubts about using a web browser:
According to the following link, in the WPF's WebBrowser you will get as much functionality as you get with JavaScript. As macros has been done before in browsers, you will certainly have enough events to do what you want.
What functional differences exist between WPF and WinForms WebBrowser control?
If you don't feel like you need the WebBrowser control, run from it while you can. A browser in a Desktop GUI can help a lot, but it comes at a cost.
However, if you feel like using one, you might want to give different browsers a try. The ASP.NET designer at MonoDevelop for instance, was developed with Mozilla Composer (Gecko engine) a while ago and before WebForms got so unwanted, there was a project to develop that from scratch using the WebKit engine.
I have written something about WebBrowser way back. You can try this if you want :
http://www.dotnetfunda.com/articles/article840-working-with-webbrowser-in-wpf-.aspx
Thanks