Binding WebBrowser content in WPF

WPF, MVVM Comments

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.

Reactivating this site

Site news Comments

germany.hamburg

Yes, this blog is still alive, though the last post is about two and a half years old.

It has happened a lot since then, but it can be condensed in two points: a) I moved again, this time to Bernau am Chiemsee at the “other end” of Germany, and b) I got married. And the latter caused the former 😃

Anyway, after 30 month of silence I think I should reactivate this blog. In the past I hesitated because most of the time I thought my topics are too trivial to write about. But that’s because whenever I had a particular programming error, I thought about it and tried to solve it. But at the point of the solution I’m already so familiar with the problem that I think it’s not interesting enough anymore to blog about it.

But on the other hand, other might have had the same problem, so why not help them and publish a possible solution? At least Google will find it.

Additionally blogging will help me to sharpen my rusty English skills 😉

Anyway, in my profession and in my spare time I deal with WPF, IoC containers, ASP.NET MVC, NoSQL databases (RavenDB in particular) among others, so you know what to expect in the future.

Sharing Extension for Graffiti

Graffiti Comments

Two weeks ago Telligent published the second beta of their upcoming new product Graffiti. It is a simple lightweight content management system. And by simple I don't mean lame. Far from it! It is simple in the sense of easy deployment, management, and publishing.

Additionally it's easy to extend. Keyvan, who I got to know and appreciate while working on the Community Server Modules, already wrote several extensions for Graffiti. To wrap up all his addons and provide a simple installation experience he started the Graffiti Extras project on CodePlex. And he was kind enough to accept me as a contributor.

So here it is, my first extension for Graffiti. In fact, I was inspired by Danny Douglass' Social Bookmarks extension for BlogEngine.NET. It enables you to link your posts to some of the most popular social bookmarking sites. The image to the right depicts an exemplary post with the extension rendered below.

Implementation

The Sharing extension is implemented as a so called chalk. Think of chalks as of macros. How to write your own chalk is well-documented, so I won't describe how I implemented the Sharing extension. If you want to have a look at the sources, go to the GraffitiExtras project on CodePlex and either download them or browse them online.

Installation

To install the Sharing chalk (and all other extensions provided in Graffiti Extras) download the attached ZIP File. This archive contains two root folders: in the bin folder you can find the GraffitiExtras.dll which you must drop into the bin folder of your Graffiti installation. The second folder, sharing-images, contains two flavors of icons in different sizes (16x16, 24x24, 32x32, and 48x48) for several social bookmarking sites (original icons are provided by FastIcon). Either copy that folder entirely or only the desired flavor/sizes somewhere to the Graffiti web folder.

Usage

To add the sharing extension to your posts, you just have to add a single line to your theme file:

$sharing.Write($post, "<image folder>")

Replace image folder with the path to the desired images. E.g. if you have copied the entire sharing-images folder to the root of your web application, and you want to see the round images with a size of 16x16, you would add following line:

$sharing.Write($post, "/sharing-images/circle/16x16/")

By default the different images are separated by a non-breaking space (&nbsp;) but you can change that with the optional third parameter:

$sharing.Write($post, "<image folder>", " | ")

.NET-Forum.de launched

Community Server, Community Comments

.NET Forum

A couple of days ago Jan Welker launched a new German .NET related community site, .NET-Forum.de. I didn't expect the developsphere to require just another site, but there are already 51 users registered, even though the site wasn't advertised anywhere except the dotnet-snippets.de newsletter.

Jan set up Community Server 2007.1 to drive the site (Did you know that .NET related non-profit communities may receive a free license?) I try to support Jan whenever he experiences issues with CS or has a configuration question. So for me it's an appreciated opportunity to get to learn CS's forum capabilities (Till now I only used the blogging part.)

I wish Jan success, and maybe this post will lead some more people to his site.

String.IsNullOrEmpty as Extension Method

.NET Comments

Most you will probably know about Extension Method introduced with C# 3.0. If not, I strongly recommend to read ScottGu's explanation.

Anyway, a couple of days ago Brad Wilson posted an experiment:

What I wasn't sure was whether or not you could call these extension methods when you have a null instance of the object, since they're instance methods. The C++ guy in me said "sure, that should be legal", and the C# guy in me said "it's probably illegal, and that's too bad". Amazingly, the C++ guy in me won!

This code executes perfectly:

using System;

public static class MyExtensions {
    public static bool IsNull(this object @object) {
        return @object == null;
    }
}

public class MainClass {
    public static void Main() {
        object obj1 = new object();
        Console.WriteLine(obj1.IsNull());

        object obj2 = null;
        Console.WriteLine(obj2.IsNull());
    }
}

When you run it, it prints out "False" and "True". Excellent!

When I read that I immediatley thought of another application. I guess all my readers are familiar with String.IsNullOrEmpty which was introduced with .NET 2.0. So I asked myself if you can make IsNullOrEmpty a parameterless extension method:

using System;

public static class MyExtensions
{
    public static bool IsNullOrEmpty(this String s)
    {
        return String.IsNullOrEmpty(s);
    }
}

public class MainClass
{
    public static void Main()
    {
        string s1 = "Hello world";
        Console.WriteLine(s1.IsNullOrEmpty());

        string s2 = null;
        Console.WriteLine(s2.IsNullOrEmpty());
    }
}

Again, it prints out false and true. And in my opinion this syntactic sugar looks much more elegant than the ordinary String.IsNullOrEmpty(s2)`.

If only C# would support extension properties...