June 28, 2008
Another sf prediction lets us down
BBC News: "Martian soil appears to contain sufficient nutrients to support life - or, at least, asparagus."
In all the mass of science fiction dealing with the terraforming and colonisation of Mars, I don't think anyone has ever depicted a market garden economy based on asparagus. Reality-shaping drugs? Sure. Angels? Absolutely. Elvis? Everywhere. Paul McAuley even placed a side bet on yaks. But nobody ever anticipated this, did they?
June 18, 2008
Wellington .NET User Group - Introduction to DSL Tools
Thanks to everyone who came to this evening's session on the Visual Studio DSL Tools. Here are the slides and a reference version of the demo, plus (sketchy) notes on how to build up the demo starting from the beginning.
If you're not familiar with the motivating domain modelling/ORM example used in the demo, check out LightSpeed here. If you want to see how the sketchy demo builds up into a real working designer, you can download LightSpeed free.
I'll try to write up some more notes on some of the aspects I glossed over, particularly how to generate code from the DSL at compile time and the joys of building and deploying custom tools.
June 11, 2008
Why the Silverlight VisualStateManager is wrong
Silverlight has a control templating system similar to that of Windows Presentation Foundation. However, Silverlight and WPF take different approaches to updating the user interface as the user interacts with it. WPF uses triggers: the creator of a template specifies changes to the template to be applied under certain conditions. Silverlight instead has the Visual State Manager: the creator of the control puts it into different visual states, and the creator of the template applies UI effects according to the visual state.
The difference is clearer with an example. Consider how we would make a button become highlighted the mouse is over the button. For example, the Windows XP Start button glows when the mouse is over it; normal dialog buttons display a yellow border. In WPF, we would achieve this effect in the button template with a Trigger on the IsMouseOver property. In Silverlight, we would handle the MouseEnter event in the control code by setting the button's visual state to "Hot", and then in our template by including a VisualStateManager segment specifying how to handle the "Hot" state. (I'm simplifying a bit here. Ian Griffiths has a great explanation.)
There's been some thoughtful back and forth about these different approaches, and the rumour is that WPF will be incorporating the Silverlight approach. Let's hope not. Although the Silverlight approach has some attractive features, it fundamentally breaks the lookless model of WPF. It forces a control to have brittle knowledge of its user interface. It takes the so-called "parts and states pattern," which is not so much a pattern as an admission of failure, and makes it the only game in town.
That's not to say that the Silverlight approach doesn't have its good points. The ability to orthogonally decompose visual state into its components, and to encode once and for all when a button should be hot and when it shouldn't, is attractive. At present, a WPF template author needs to consider all the possible conditions that should cause a button to display as hot. For a more complex control with a more complex visual model, that invites bugs. The "parts and states" model adopted by Silverlight, it is argued, makes the control's visual contract more explicit. Here is a list of the visual parts and the visual states, says the control: you decide how you want them represented, and I will look after the rest.
The problem with the Silverlight approach is that it requires the control author to anticipate the possible user interfaces that designers might come up with. Let us suppose, for example, that the author of the Button code, being a developer, hadn't really noticed that user interaction had moved on since Windows 3.x, and declared only two visual states, "Normal" and "Pressed." A Silverlight designer who wanted their buttons to respond like XP or Vista buttons would be out of luck. There is no way for the Silverlight template to represent "hotness," because the concept doesn't even exist. By contrast, a WPF designer could create their own visual states as they saw fit.
This is not just about the subtleties of graphic design, or the joys of a full-on developer-designer workflow. The ability to trigger off any property is fundamental to visualising data with WPF. Consider a custom text box for editing numeric values: the sort of thing you'd be using in a line of business application, a "GUI green screen" with none of your beret-wearing designers involved. You might need to display negative values in bold, red text so your users can easily identify deadbeats and go remonstrate with them. No problem: add a trigger for the Value property. (You'll need a value converter to translate a value into a sign, but you can still create that without having to modify the underlying control.) In Silverlight, you'd have to petition the control author (who might be a third-party vendor) to add a "NegativeValue" visual state. And then next day you'd find that you also needed a "getting low" state so your users could ring people up and advise them to top up their account quick...
The Silverlight VisualStateManager model, quite simply, cuts off the ability to create even the most rudimentary adaptive data visualisations. As in the Windows Forms era, every view option requires support in the control itself. Users of a control can no longer choose their own criteria for changing the display.
What about the control contract argument? A WPF control can easily expose a suggested contract if the developer has one in mind. Again, consider the button example. If the Button developer wants to give the template author a shortcut, he can create an ActivationStatus property of enum type with possible values Normal and Pressed. A designer who is building a Windows 3.x retro theme can stick to using those properties. A designer who wants pulsing glows and mellow floating clouds, and finds that the ActivationStatus property doesn't meet his needs, can ignore it and go straight for the mouse events. (The Mindscape NumericTextBox does something like this, by offering a NegativeStyle property for the common case, and a triggerable Value property for custom cases. Not quite the same, but you get the idea.) The Silverlight VisualStateManager does have the advantage that controls are required to declare their visual states through attributes, which makes it easier for tools such as Blend to tell designers what states they need to handle; but this could easily be added to WPF by defining a property-level attribute. For example, our Button developer could place a hypothetical [VisualState("Activation")] attribute on the ActivationStatus property.
It has to be said that, given the constraints of Silverlight, the parts and states model, and therefore the Visual State Manager, does make some sense. Silverlight's data binding is much weaker than WPF's; therefore Silverlight control developers are much more dependent on writing procedural code and calling setters on their template elements. (In WPF you would normally prefer a TemplateBinding; that is, the template element reflects information of interest from the control's lookless model, rather than the control code pushing that information to distinguished elements known to it at design time.) In order to call a setter, you need to know what your template elements are and have a way to locate them, and that drives you towards the parts model. The parts model drives you towards assumptions about how your control's UI will be made up. And if you are making assumptions about how your control's UI will be made up, then you can probably make some corresponding assumptions about how your control's UI will behave. In which case you might as well code up those assumptions and spare the template author the hassle of writing <Trigger Property="IsMouseOver" Value="True"> for the eight millionth time. It is indeed an exercise in the art of subsetting.
However, it's important to realise that the ultimate justification for the VisualStateManager lies in covering for present weaknesses of Silverlight. In the WPF environment, where we already have template triggers and powerful data binding, VisualStateManager would be a misguided step towards a closer coupling of controls and templates. The effort required to add VisualStateManager to WPF would be better placed adding triggers and data binding to Silverlight, and I hope that's what Microsoft does.
June 05, 2008
Palmerston North .NET User Group - Introduction to WPF
I took the "Introduction to Windows Presentation Foundation" talk to Palmerston North tonight and had a great time. Thanks for your hospitality! I'm constantly amazed at how active the so-called regional user groups are. Thanks in particular to the chap (sorry, didn't get your name) who came all the way from Wanganui -- I hope it was worth the journey.
The slides and demos are at http://hestia.typepad.com/flatlander/2007/11/wpf-user-group.html. Most of the demos include readme.txt files highlighting what the demo is trying to show and/or explaining how it works.
Also, there's a more step-by-step walkthrough of the list box earthquake map demo at Five steps to WPF data visualisation.