Did you ever want to embed a browser in a WPF application, to host a help file or to access an intranet site? Did you ever want to impress your girl friend by building a fancy browser yourself, like YouCube? If so, your obvious choice would be to drag and drop a native WebBrowser Control into your application. Well, hold your horses (or rather: hold your mouse). The standard WPF WebBrowser control that sits in your Visual Studio toolbox is just an ultra-thin wrapper around Microsoft's Internet Explorer ActiveX. This wrapper is so thin that it's not even aware of such celebrated WPF features as transformations and styles. If you use the control in any container that is just a little bit dynamic, then it will simply go berserk. Here's an example. I wrapped a native WebBrowser control in a ScrollViewer, then applied some gentle transformations. The browser just walks happily over the entire GUI:
So if you're planning to build a user experience like in the following screenshot (which is the already mentioned YouCube), then forget about Internet Explorer, and start looking for an alternative:
The alternative solution basically requires 3 ingredients:
- a browser, obviously,
- an SDK to get programmatic access to the browser's core functionality, and
- a WPF wrapper that does more than just adding a WindowsFormsHost element.
An interesting alternative comes from an unexpected source:Google. Chromium is the open source browser on which Google Chrome is based. It's unbranded, it doesn't automatically update, and it doesn't send crash reports and usage statistics to the Googleplex (all details here). Cool, that's just what we want in our application!
Awesomium is a platform independent C++ software library that allows developers to embed Chromium in their own applications. Older versions were released as open source, but the code is currently being productized.
A real WPF wrapper
Chris Cavanagh built WPF Chromium, which exposes Awesomium as a .NET and WPF control. Feel free to check the Sources and References.
To use WPF Chromium's WebBrowser control in your own application, add a reference to the .NET dll's:
You also need to make sure that the (non-.NET) Awesomium dll's end up next to your executable:
Finally, don't forget to compile in 32-bit mode:
My guess: we now have a serious challenger for IE.
Battle of the Browsers
I built a little torture chamber to see how far we can stretch the native IE browser and WPF Chromium. The sample application straps a browser in a ScrollViewer and tries to shake it around with transformations. It also implements scrollwheel-zooming and left-button panning, and last but not least: it tries to override the scrollbar style. Here are some observations:
On the other hand, IE is a much better Silverlight host. When you navigate to this beautiful but technically rather simple Silverlight site, WPF Chromium -or the underlying Awesomium- experiences problems in tracking the mouse position:
This is as good as it gets for the Internet Explorer ActiveX. For the rest of the article, you may ignore it: the control browses but don't expect anything else from it. And by the way: there's no improvement on the horizon: WPF 4.0 still has the same IE ActiveX wrapper.
A small test with some slider controls rapidly reveals that transformations are not an issue for WPF Chromium. Here's an example:
Zooming via a slider control is not so sexy; so I implemented zooming through the scrollwheel. Works fine. And now that we're talking about the scrollwheel: both browsers support scrollwheel panning. Unfortunately Chromium doesn't show the cursors (that's a weird user experience). So just for fun I implemented left-button panning. By holding the left button and moving the cursor, you can drag the underlying bitmap around. It's a nice replacement of scrolling, but the first symptoms of overstressing the control appeared: you need to specify a fixed size for the displayed page (continue reading for more details).
There's not much to style in a Browser control: it just renders a bitmap, right ? Wrong ! To offer you the pleasure of scrolling, a browser calculates the estimated size of the rendered page. It then displays its own set of native Windows GDI scroll bars . You can't override these scrollbars, but you can hide them, and wrap the browser control in a -stylable- WPF ScrollViewer control. You need to know the estimated size of the underlying (virtual) bitmap, which unfortunately is not accessible. As a work around set it to fixed size. If you set it too small, you can only scroll through a part of the site, but setting it too large will horribly slow down the scrolling experience. Here's an example of styled scrollbars (remember: de gustibus et coloribus non est disputandum also applies to styles):
Here it is, a demo of Chromium and Awesomium, by U2UConsultium : U2UConsult.ChromiumBrowser.Sample.zip (9,09 mb)