Binding HTML to a WebView with Attached Properties

It's been said that if you aren't data binding you aren't really using Xaml, and a frequent topic on the forums is how to bind HTML from a data model to a WebView.

The problem: we bind data to properties, but the WebView doesn't have a property to bind to. An app sets the WebView's HTML by calling the NavigateToString method.

The solution: create our own property to bind to.

Windows.UI.Xaml has the concept of attached properties which let us create a stand-alone property which can "attach" to any object, such as our WebView. We can create an attached property "HTML" that when changed calls NavigateToString. We can then bind it to HTML data in our data model.

First create a new class to hold the attached property, then create the attached property inside it.

Visual Studio includes a snippet to help with this: type “propa”<tab><tab> and the basic skeleton for an attached property will be inserted. Change the return type to “string” and the name to something appropriate. I named my property “HTML”. The snippet will take care of synchronizing your change to the whole property. Set the ownerType in the RegisterAttached call to the name of your class.

class MyExtensions

{ public static string GetHTML(DependencyObject obj) { return (string)obj.GetValue(HTMLProperty); }

    public static void SetHTML(DependencyObject obj, string value)

    { obj.SetValue(HTMLProperty, value); }

    // Using a DependencyProperty as the backing store for HTML. This enables animation, styling, binding, etc...

    public static readonly DependencyProperty HTMLProperty = DependencyProperty.RegisterAttached("HTML", typeof(string), typeof(MyExtensions), new PropertyMetadata(0)); }

At this point we have a property which can be set to a string, but it isn’t connected to the WebView’s document. To do that we need to add a change handler to the property’s PropertyMetaData:

       public static readonly DependencyProperty HTMLProperty =
           DependencyProperty.RegisterAttached("HTML", typeof(string), typeof(MyExtensions), new PropertyMetadata( "" ,new PropertyChangedCallback(OnHTMLChanged)));

       private static void OnHTMLChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
       {

            WebView wv = d as WebView;

            if (wv != null) { wv.NavigateToString((string)e.NewValue);
} }

Now all we need to do is to reference the attached property in our Xaml to bind the WebView to HTML from an “HTMLText” property in our data model:

<WebView local:MyExtensions.HTML="{Binding HTMLText}"></WebView>

The same technique can be used to enable binding RTF into a RichEditBox and for other controls which ones sets by method rather than properties.

For more on Dependency Properties and Attached Properties see:
Dependency properties overview
Attached properties overview
Custom attached properties

A full project demonstrating this for C#, VB.Net, and C++/Cx is available in the All-In-One Code Framework: How to bind HTML from a data model to a WebView 

--Rob

Follow the Windows Store Developer Solutions team on Twitter @wsdevsol