Archive for December, 2007
Introducing NHaml – An ASP.NET MVC View Engine
Tagged as GeneralI just released V1 of a little side project I’ve been working on – A “Haml”:http://haml.hamptoncatlin.com view engine for the new ASP.NET MVC framework. Check out the details and download the bits from my blog “here”:http://andrewpeters.net
Commands and controls in WPF
Tagged as WPFWindows Presentation Foundation controls are “lookless.” That is, the behaviour of the control is defined in code, but the appearance of the control is defined in a XAML template, and that template can be replaced by applications that want to customise the look of the control.
A consequence of this is that you can’t directly hook up elements of the control user interface to aspects of the behaviour. For example, suppose you’re writing a calendar control, and your default template includes “month back” and “month forward” buttons. In a Windows Forms user control design, you could hook up the Click events of these buttons to event handlers in the code, but that’s not a good design in WPF. In fact, WPF makes it pretty hard to do it at all.
Try it. Create a custom control, put a button into the default template, and assign a Click handler to the button. You’ll get a compiler error saying that a ResourceDictionary needs an x:Class attribute to support event handlers. The x:Class attribute tells the XAML compiler to create a partial code-behind class which you can extend with your event handlers. So now you can create a C# or Visual Basic file containing a partial class with the appropriate name, you can add your event handler to that, and now the control compiles. You’ve still got a problem writing your event handler, because you’re in a ResourceDictionary-derived class, not your control class, and the event is coming from the button, which doesn’t give you ready access to the control instance that you want to act on.
This alone should be a hint that this is the wrong way to go, but suppose that you manage to overcome these obstacles and implement your control using this approach. What happens when someone decides to retemplate it? Well, they put a button into their template, and now they have to create their own event handler. That’s not too painful if your user is defining the template at the window level, though it goes against the spirit of being able to restyle controls through markup alone; but it’s part of a general re-theming the user might well put the template into a ResourceDictionary, and now they have the same problems you did.
So why does WPF make it this difficult? Because WPF is trying to decouple the look of the control from the behaviour. The “look” — the template — shouldn’t have intimate knowledge of the behavioural code. The behavioural code shouldn’t be written with a specific user interface in mind. Communication between the code and the template should be loosely coupled.
One technique for this loose coupling is, of course, data binding. Elements in the template can bind to properties of the control. When the property changes, the element reflects that change, and vice versa. However, this doesn’t help us with the “month back” button: a button doesn’t have a property which changes in a useful way when the user clicks it, so we can’t use data binding to propagate this back to the calendar’s Date property. In the case of other “event handlers,” for example if the control exposes actions like Save or Update, there’s no property you could bind to even if the UI element did have something suitable.
For situations like this, WPF instead offers commands.
A command is represented by the ICommand interface, and usually implemented using the RoutedCommand class. Command objects don’t usually do much themselves: like DependencyProperty objects, they’re really just identifiers. Thus, a “month back” command doesn’t contain any logic about how to change the date on the calendar: it’s up to the calendar control (or anything else that could use a “month back” command) to decide how to handle the command. A control can consume built-in commands like Cut or Open, or can define and consume custom commands like MonthBack and MonthForward. Controls such as buttons and menu items can send these commands. And specifying which command a button sends is something we can do in pure markup, without any reference to code.
So in the calendar example, the calendar might define a custom command as follows:
public static readonly ICommand MonthBack = new RoutedCommand(...);
And the calendar control would then bind this command to an appropriate event handler:
public Calendar()
{
CommandBindings.Add(new CommandBinding(MonthBack, MonthBack_Executed));
}
Now we — and anyone retemplating the control — can define the “month back” button to send this command:
<Button Command="{x:Static c:Calendar.MonthBack}">Back</Button>
This works whether in our theme resource dictionary, or an application resource dictionary, or a window-level template.
Commands, then, are the flip-side to bindable properties in defining the control’s “templateable” interface. Properties are the part of the interface that allow the template to represent and update the state of the control. Commands are the part of the interface that allow the template to perform actions on the control. Conversely, the set of properties and commands exposed by a control defines and limits what can be done with the control through its own user interface. If a control exposes a Save method, but no Save command, then applications can only perform the Save operation from code: neither the control author nor any other template designer can declaratively create a reusable template that gives access to the Save feature.
You’ll usually find that the commands interface falls naturally out of the default template: as you add UI elements to the default template, and wish that you could implement event handlers for them, that will be a clue that the control should provide a command for this situation. However, it’s also worth considering whether methods exposed by the control should also be commands, even if your default template doesn’t surface them. Another consideration is when to move part of the action definition out of the command and into a parameter: for example, should the Month/Week/Day Back/Forward calendar commands be combined into a ChangeDate command with a parameter, so that an enterprising template designer could implement a “fortnight back” or “year forward” button if it happened to be useful in their scenario? The answers depend on the individual control, of course; but if you think of commands as the API you expose to the template designer, you shouldn’t go too far wrong.
Five steps to WPF data visualisation
Tagged as WPFAs part of my recent Windows Presentation Foundation user group tour, I’ve been doing a quick demo showing how easy it is to go in WPF from a bare-bones textual presentation to a rich visual presentation of the same data. To me, this is one of the big opportunities that WPF opens up for “ordinary” application designers, those of us living in a world where we don’t have a team of professional graphic designers dedicated to making our application look more like a car advert than a computer program. So I wanted to put together a set of demos showing how to get from the traditional “chuck it in a list box or data grid and move on to the next feature” textual UI to a simple but effective visualisation UI in a series of small and easy to grasp steps.
The motivating example I’m going to use is visualising earthquake data. This has got an obvious geographical presentation, marking up events on a map and using colour, shape and/or size to show intensity. But we’re going to start from what WPF gives us for free, and work towards the geographical presentation one step at a time.
Get the code to see what’s going on at each step.
Step 1
So let’s assume we have a collection of Quake objects, and let’s plug them into a list box.

Okay, that doesn’t look so great.
Step 2
Of course, the problem here is that WPF has no idea how to render a Quake object. The best it can do is call ToString on each one, and since I haven’t overridden ToString, that just returns the type name. One way to address this, obviously, is to override ToString, but that brings its own problems: what should the returned string look like? Will that be appropriate wherever and whenever somebody wants to display a Quake in a list? What about localisation? Besides, ToString is a dead end as far as visualisation is concerned: there’s no way a method that returns strings can help us to come up with the geographical presentation described above.
The right way to solve this is to use a data template. The data template tells WPF how to display a particular object. Data templates allow the application to decide how it wants to render the Quake object in any given circumstance — unlike ToString, which bakes the rendering into the object itself — and enables different applications, or different parts of the same application, to render the same object in different ways according to the user’s needs.
We’ll start with a simple data template, consisting of a horizontally-oriented StackPanel containing a bunch of TextBlocks.

That’s a lot better. It’s still a plain textual representation, but at least now we can see some actual information.
Step 3
We’re still not really helping the user to visualise the information. We need to use things like colour and size to supplement the text, so that the user can get an overview more easily and can quickly transfer their attention to whatever events they find particularly interesting.
A WPF data template allows us to include things other than text, and to set properties other than the textual content. We can, for example, add an Ellipse whose Width and Height are data-bound to the magnitude of the earthquake. Bigger earthquakes will have bigger circles and will therefore stand out more. We could also bind the font size to the magnitude, further emphasising the big quakes.
The display could do with being spruced up graphically, but conceptually it’s clear that we’ve managed to supplement the plain text with a visual representation. Now, however, the list box presentation itself is becoming a limiting factor.
Step 4
Windows Presentation Foundation controls are “lookless.” That is, the control defines a behaviour, independent of its display. What we think of as the “look” of a control is actually just the default template, and we can replace that if we have a different requirement.
In the case of a list box, the behaviour of a list box is to display a collection of items and track which one is (or which ones are) selected. By default, it displays those items one above the other in a big vertical stack, but there’s nothing inherent in the description of a list box’s behaviour that ties it to a big vertical stack. And indeed the WPF list box allows us to replace this default display via the ItemsPanel property.
For a geographical presentation, we need a panel that allows us to place items at coordinated positions. In WPF, that’s the Canvas panel type. We’ll set the background of the canvas to be a map.
We also need to update our data template again, to bind the Canvas.Top and Canvas.Left attached properties so that the items are positioned correctly on the canvas. Unfortunately, there’s a small wrinkle here. Defining and binding these properties on the item data template doesn’t achieve anything. The reason for this is that our template instantiations are actually getting wrapped in ListBoxItem controls, and it’s these ListBoxItems that are being placed on the Canvas. We need to set the Canvas attached properties on the ListBoxItems, not the data template, and to do this we have to use the ListBox.ItemContainerStyle property.
Once we do that, the members of the list appear positioned in the list box according to their geographical location.
This is the breakthrough! Our users will now find it much easier to see the set of earthquakes as a whole and to visualise the relationships between them. The nicest thing about this is that it is still a working ListBox — all the mouse hit testing, keyboard navigation, selection tracking etc. is still taken care of for you even though the visuals are so dramatically different from what we expect in a ListBox.
(Incidentally, the code as supplied incorrectly displays the quakes with their top left at the epicentre, instead of centred on it. This is easily fixed; I didn’t bother because it’s not particularly germane to the idea of the visual presentation.)
Step 5
We can still go a little bit further. At the moment we are using a single template for all earthquake events. With our data set, that’s okay, but if we had a lot more little earthquakes then we’d end up with a lot of “noise” on the graph, making it hard to see the significant quakes. We could partly solve that with a more complicated data template and some new converters — say, making the relationship of circle size to magnitude non-linear, and binding the visibility of the caption to the magnitude so it’s hidden for small quakes — but this is fiddly and limited, and loses our intent in a maze of detail.
What we really want is a way to say that different quakes may have different representations, and to capture in a central location our criteria for choosing between them. This is what a template selector gives us. So in our final step, instead of having one template, we’ll have three templates, and instead of specifying the template via the ItemTemplate property, we’ll specify a selector via the ItemTemplateSelector property. Our selector is pretty simple — it just checks whether the magnitude is below an “insignificance” or above a “megacatastrophe” threshold, and chooses the small, normal or big template accordingly.
Of course, with graphic design like this, there will be some who will argue that I should have stopped with the textual representation.
Conclusion
How much effort is involved in building something like this in WPF? This demo would probably take an hour or two to build from scratch for a knowledgeable WPF developer, assuming you already had a suitable data model (which is a reasonable assumption for a line of business type application), and that there was no argument about or fiddling around with the actual design itself. It would take a bit longer to sand down some of the rough edges. You can imagine that many visualisations such as Gantt charts would be equally quick, and some such as scatter graphs could be even quicker.
As I’ve said elsewhere, I don’t buy the argument that WPF is primarily for high-end graphical applications and that it’s an inappropriate choice for business applications. The combination of data binding, lookless controls and the unified programming model for text, controls and graphics makes WPF an enormously productive platform for anything that goes even a little way beyond the “GUI green screen.” Once the business managers and the usability folks realise how cheaply they can have it, data visualisation is going to be one of the killer applications for WPF.
Code Metrics
One thing I like about open source projects is that it’s usually fairly easy to find out some metrics about the code. Things like: test coverage, LOC and the test code to production code ratio. In particular test coverage is one of the first things I look at when evaluating a piece of software.
So in the interest of transparency, I thought I’d share some of the metrics we track for LightSpeed.
h3. Visual Studio 2008 Code Metrics
Visual Studio 2008 can now calculate code metrics. Here’s the project level results for the LightSpeed framework:
| *Project*|Framework|
| *Configuration*|Release|
| *Scope*|Project|
| *Assembly*|C:\mindscape\code\LightSpeed\Trunk\Bin\Release\Mindscape.LightSpeed.dll|
| *Maintainability Index*|86|
| *Cyclomatic Complexity*|2,116|
| *Depth of Inheritance*|5|
| *Class Coupling*|285|
| *Lines of Code*|3,391|
h3. Test Coverage
We run NCover as part of our build process. Here’s the output:
-----------------------------------------
NCoverExplorer.Console 1.3.6.26
(c) 2006 Grant Drake
http://www.ncoverexplorer.org/
-----------------------------------------
Using .config file: C:\Documents and Settings\Administrator\Local Settings\Temp\tmp5B20.tmp
-- Options:
Project Name: LightSpeed
Acceptance%: 90%
Sort: Name
Filter: None
Xml Report: ..\Artifacts\CoverageSummary.xml
Html Report: N/A
Report Type: ModuleClassSummary(4)
Merge To: N/A
Exclusions: (Included in report footer section)
- any -1 matching (IsRegex=False)
97.1% coverage, 419 unvisited sequence points in 7 files.
h3. Test Code to Production Code Ratio
Running the VS code metrics across a our unit test projects gives a LOC of *2974*. This gives us:
*Test Code to Production Code Ratio: 2,974/3,391 = 0.87*
I think commercial software companies need to start being a bit more transparent about code quality metrics. What do you think?
![]()
BrainDump (1)
Community Code (1)
Events (6)
General (27)
Lab Samples (2)
LightSpeed (112)
MegaPack (3)
News (37)
Products (51)
Projects (4)
Screencast (6)
Silverlight (1)
Silverlight Elements (1)
SimpleDB Management Tools (8)
Visual Studio (4)
VS File Explorer (4)
WPF (28)
WPF Diagramming (11)
WPF Elements (15)
WPF Property Grid (20)
![]()
February 2010
January 2010
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
December 2007
November 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007




Posted by Andrew Peters on 19 December 2007



