Monday, 16 December 2013

Chemistry and WPF

I remember many years ago turning to a spoof advert in VIZ Comic for 'Over Your Head Computer Magazine'. It was a brilliant, if coarse, pastiche of your typical home computer mag, except that it set the tone with a front page headline screaming 'IT'S TOO LATE! YOU CAN NEVER HOPE TO CATCH UP!'

I laughed at it at them time not realising that I'd be laughing at myself a decade or so later. There comes a point in every IT professional's career when they realise that they've fallen behind and have to risk a heart attack running to catch up. So it was with me and Windows Presentation Foundation (WPF).

I'd avoided learning WPF as I spent most of my time mired in the archaic but easy world of Windows Forms (WinForms). WinForms' main weaknesses are also its strengths: you are limited as to what you can do with the user interface elements, so you spend most of your time writing business logic code. A Button will support a handful of properties that you aren't inclined to alter on the whole: you just want to set the caption, put it in a convenient location and wire up a Click event to it so it does something useful.

With WPF it seems like you have to learn a shedload of new concepts before you can even think of doing this kind of coding. Dependency properties, content controls, routed events, styles, themes, templates...all these present hurdles that must be got over before coding can begin in earnest. I picked up Adam Nathan's excellent book on the subject with the intention of working through it, and several years later I'm still working through it.

So, I decided that the only way to teach myself WPF was to actually start working on a project that would benefit from it. I started out my career as a chemist but drifted into programming almost accidentally. I try to bring the two together by heading up the Chemistry for Word project, aided and abetted by a team of thoroughly capable and enthusiastic volunteers. Currently we are integrating the fine ChemDoodle editor to edit chemical structures, and we'll be using it for the foreseeable future, but I just wanted to see whether or not it would be possible to do the same thing in WPF. 

So, why use WPF for editing chemical structures? Well, it has several appealing advantages over other ways of doing this:
  • It uses DirectX and is very quick;
  • It uses high-level concepts - Shapes - to describe objects on screen.  Shapes provide their own event handling, and styling so you can manipulate them directly in XAML;
  • You can use your existing C# knowledge to engineer the actual code itself.
Moreover, it makes  difficult things a lot easier, even if it's difficult itself to learn.  Take for instance the drawing of chemical bonds.  Chemists use a certain convention to convey stereochemistry known as the hash-wedge convention.  Here's 1-phenylethanol drawn using this convention:

Drawing the hash bond to the hydrogen atom using conventional Windows GDI calls is a pain in the nether regions as you have to draw lines perpendicular to the direction of the bond that gradually taper out.  But with WPF it's much simpler.  You define a Shape object that describes the overall outline of the bond, a Brush object that describes the hash pattern, and then apply the Brush to the Shape using a BrushTransform to rotate it. You get the angle of rotation using a customer ValueConverter object that takes the bond object and spits out the angle at which it's drawn, which you can then bind to the BrushTransform using a XAML Style object. 

The issue with this approach is the same issue as with every other WPF approach to solving a problem.  It's not that it's difficult - it isn't.  It's that it's difficult to discover.  WPF has gained an unenviable - and justified - reputation for size and complexity and it's hard to pin down the most effective way of performing a task. 

So, I think it's worth my sharing my experiences with WPF as I build this chemical editor control.  I will publish various snippets of code as I deal with interesting problems I encounter during the development process.  I hope that in so doing I'll go some way to demystifying WPF for the uninitiated. 

One final point:  The new Windows Runtime is a separate subsystem altogether from WPF, and there has been a lot of talk of WPF itself being deprecated.  I don't believe that this is currently in the offing as many business users won't be using applications written to run on the new Metro interface.  Besides which, both systems make extensive use of XAML so learning this will stand you in good stead for the future.