Binding WebBrowser content in WPF
When you’re using a WebBrowser control in your WPF application, you may have noticed that you can’t bind the control’s content. WebBrowser has no property to set its content but a method named NavigateToString
. So when you’re following a strict MVVM approach you’re lost because you don’t want any code-behind for your views.
But then there are attached properties. As their name implies they allow you to attach new properties to existing dependency objects. In your XAML code you apply such a attached property to your element and can access it as any other property of the object.
Ok, first here’s the code of an attached property to set a WebBrowser
’s content:
public class WebBrowserHelper {
public static readonly DependencyProperty BodyProperty =
DependencyProperty.RegisterAttached("Body", typeof (string), typeof(WebBrowserHelper), new PropertyMetadata(OnBodyChanged));
public static string GetBody(DependencyObject dependencyObject) {
return (string) dependencyObject.GetValue(BodyProperty);
}
public static void SetBody(DependencyObject dependencyObject, string body) {
dependencyObject.SetValue(BodyProperty, body);
}
private static void OnBodyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
var webBrowser = (WebBrowser) d;
webBrowser.NavigateToString((string)e.NewValue);
}
}
The static BodyProperty
defines the type of the attached property: its name is Body
, the type is string
, and whenever it is changed the method OnBodyChanged
should be called.
The accessors for a attached property must be conventionally named SetXxx
and GetXxx
. They are called whenever you set or get the property’s value.
Last but not least OnBodyChanged
is called when the value of the property has changed. The first parameter is the object the property is attached to, so we can cast it to WebBrowser
and call its NavigateToString
method.
The actual usage of the new Body property is pretty simple:
<WebBrowser
src:WebBrowserHelper.Body="{Binding MyHtml}"
/>
given that the ViewModel has a property named MyHtml
providing the desired content for the control.
A complete sample application is available on GitHub.
Comments
Anonymous
Thanks mate
worked for me.
Anonymous
Good article solved my problem of not having Source as a dependency property, used same to bind with Source
Thanks
Anonymous
Very nice article. I really enjoyed it reading. And it also cleared lot of my doubts about WPF WebBrowser control. Some other article too helped me lot in completing my task. These article are…
http://mindstick.com/Articl…
http://www.c-sharpcorner.co…
http://msdn.microsoft.com/e…
Anonymous
Thanks a lot buddy
Anonymous
Hi,
Its not working. I get the error at run time xaml markup threw an exception.
Please provide the appropriate solution.
Thanks
Anonymous
It worked for me.. thanks
Anonymous
hey this looks just what I need does anyone have this solution for silverlight 5? Has anyone tried this for silverlight project?
thanks again, slguy
Anonymous
hi
can u post this in vb.net?
im having difficulty translating the first line. (DependencyProperty.RegisterAttached)
thanks!
ThomasG
Thanks for this code. It was very useful.
James
This post is great but the XAML window will throw an exception. To solve that you can look at this: http://stackoverflow.com/qu…
Thomas Freudenberg
What kind of exception? Do you mean the case when this behaviour is used inside a DataTemplate?
Nitish
There is an ‘AirSpace Problem associated with WebBrowser’. Can you please help me resolving the problem WPF 3.5.
Problem : Not able to show any other WPF Control on top of WebBrowser control.
Thomas Freudenberg
There’s no simple solution for the airspace problem. You may consider using the CefSharp (http://cefsharp.github.io/) “http://cefsharp.github.io/)”) instead of the WebBrwoser control. It’s a wrapper around CEF, the Chromium Embedded Framework.
Raphael Ulrich
When you want to show two WebBrowsers at the same time, it does not work, because the DependencyProperty is static and the value is shared with all the WebBrowsers using it.
Dwayne
I have tried this and see this site is fairly old. Rookie question. I used this class in a folder called “HelperClasses”. How do I write the xmnls to look for HelperClasses/WebBrowserHelper in my solution?
Thomas Freudenberg
Dwayne, you have to specify the namespace which contains your helper class. E.g. if you
have put WebBrowserHelpers into MyProject.HelperClasses, to have to declare
``
The you can use this XML:
``
kirko77
I don’t get it… this example simply displays the link string instead of the actual webpage.
How do you load up the actual page? Thanks
Thomas Freudenberg
That’s the intention of this task: to bind the content of the WebBrowser control to a property. Just imagine you want to display some dynamic HTML created by your application at runtime.
kirko77
Got it, thanks! I already found a very similar example where it actually displays the webpage.
Thanks for clarifying!
Sanjay Singh
:) keep it up
Leave a Comment
Your email address will not be published. Required fields are marked *