Let\'s say that WPF WebBrowser control
shows some navigation errors and the page is not showing.
So there is an exception of WPF WebBrowser contro
It's an old question but since I have just suffered through this, I thought I may as well share. First, I implemented Markus' solution but wanted something a bit better as our Firewall remaps 403 message pages.
I found an answer here (amongst other places) that suggests using NavigationService
as it has a NavigationFailed event.
In your XAML, add:
<Frame x:Name="frame"/>
In your code-behind's constructor, add:
frame.Navigated += new System.Windows.Navigation.NavigatedEventHandler(frame_Navigated);
frame.NavigationFailed += frame_NavigationFailed;
frame.LoadCompleted += frame_LoadCompleted;
frame.NavigationService.Navigate(new Uri("http://theage.com.au"));
The handlers can now deal with either a failed navigation or a successful one:
void frame_NavigationFailed(object sender, System.Windows.Navigation.NavigationFailedEventArgs e)
{
e.Handled = true;
// TODO: Goto an error page.
}
private void frame_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
System.Diagnostics.Trace.WriteLine(e.WebResponse.Headers);
}
BTW: This is on the .Net 4.5 framework
It is also possible to use dynamic
approach here.
wb.Navigated += delegate(object sender, NavigationEventArgs args)
{
dynamic doc = ((WebBrowser)sender).Document;
var url = doc.url as string;
if (url != null && url.StartsWith("res://ieframe.dll"))
{
// Do stuff to handle error navigation
}
};
I'd been struggling with this issue for some time. I discovered a cleaner way to handle this than the accepted answer. Checking for res://ieframe.dll didn't always work for me. Sometimes the document url is null when a navigation error happened.
Add the following References to you project:
Create the following helper class:
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using System.Windows.Controls;
using System.Windows.Navigation;
/// <summary>
/// Adds event handlers to a webbrowser control
/// </summary>
internal class WebBrowserHelper
{
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:FieldNamesMustNotContainUnderscore", Justification = "consistent naming")]
private static readonly Guid SID_SWebBrowserApp = new Guid("0002DF05-0000-0000-C000-000000000046");
internal WebBrowserHelper(WebBrowser browser)
{
// Add event handlers
browser.Navigated += this.OnNavigated;
// Navigate to about:blank to setup the browser event handlers in first call to OnNavigated
browser.Source = null;
}
internal delegate void NavigateErrorEvent(string url, int statusCode);
internal event NavigateErrorEvent NavigateError;
private void OnNavigated(object sender, NavigationEventArgs e)
{
// Grab the browser and document instance
var browser = sender as WebBrowser;
var doc = browser?.Document;
// Check if this is a nav to about:blank
var aboutBlank = new Uri("about:blank");
if (aboutBlank.IsBaseOf(e.Uri))
{
Guid serviceGuid = SID_SWebBrowserApp;
Guid iid = typeof(SHDocVw.IWebBrowser2).GUID;
IntPtr obj = IntPtr.Zero;
var serviceProvider = doc as Microsoft.VisualStudio.OLE.Interop.IServiceProvider;
if (serviceProvider?.QueryService(ref serviceGuid, ref iid, out obj) == 0)
{
// Set up event handlers
var webBrowser2 = Marshal.GetObjectForIUnknown(obj) as SHDocVw.IWebBrowser2;
var webBrowserEvents2 = webBrowser2 as SHDocVw.DWebBrowserEvents2_Event;
if (webBrowserEvents2 != null)
{
// Add event handler for navigation error
webBrowserEvents2.NavigateError -= this.OnNavigateError;
webBrowserEvents2.NavigateError += this.OnNavigateError;
}
}
}
}
/// <summary>
/// Invoked when navigation fails
/// </summary>
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", Justification = "consistent naming")]
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1306:FieldNamesMustBeginWithLowerCaseLetter", Justification = "consistent naming")]
private void OnNavigateError(object pDisp, ref object URL, ref object Frame, ref object StatusCode, ref bool Cancel)
{
this.NavigateError.Invoke(URL as string, (int)StatusCode);
}
}
Then in your window class:
// Init the UI
this.InitializeComponent();
this.WebBrowserHelper = new WebBrowserHelper(this.MyBrowserPane);
// Handle nav error
this.WebBrowserHelper.NavigateError += this.OnNavigateError;
I'm struggling with a similar problem. When the computer loses internet connection we want to handle that in a nice way.
In the lack of a better solution, I hooked up the Navigated event of the WebBrowser and look at the URL for the document. If it is res://ieframe.dll I'm pretty confident that some error has occurred.
Maybe it is possible to look at the document and see if a server returned 404.
private void Navigated(object sender, NavigationEventArgs navigationEventArgs)
{
var browser = sender as WebBrowser;
if(browser != null)
{
var doc = AssociatedObject.Document as HTMLDocument;
if (doc != null)
{
if (doc.url.StartsWith("res://ieframe.dll"))
{
// Do stuff to handle error navigation
}
}
}
}