WPF, or how trees can be hard to climb

Paul Klee-Homes Of The TreeIntroduction

This article is meant to deeply scare you, wannabe WPF developers. Seriously, consider these facts before you enter the WPF door. For those who dare read on, here’s the full story…

Since .Net 3.0, Windows Presentation Foundation (WPF) has been proposed by Microsoft as the framework of choice for developing user interfaces. The introduction of Windows 8.0 caused a bit of panic as developers felt that WPF and .Net were going to join the fate of Silverlight, but so far there have been no signs of this. If anything, it’s clear that some form of WPF will be the UI technology of the future, either in the shape of WPF itself or its new XAML offspring. So my perception is that a developer working on microsoft systems should be well aware of these technologies. But is it easy to jump onboard? After using WPF for quite some time in different projects, I can say that unfortunately the answer is no, you are definitely not going to have a free ride this time. Why?

The language of trees: XAML

WPF uses XML files to describe the user interface. The main conceptual difference between coding a UI in c# and XAML is that c# is an imperative language, whereas XAML is a declarative one, and thus it describes more of the “what” than the “how”. C# is a list of steps in cronological order; with XAML you describe the logic containment of user interface items and let the runtime build the objects in the right order and connect them properly. C# is a sequence of steps, XAML is a tree (as XML).
From a conceptual perspective, this is all good and dandy; but there are dark sides to it.
The main trouble is that you have to learn this new XAML language. You were thinking you would be drawing shapes and panels to define your UI, and you find yourself browsing XML files. It would be great to define the visual appearance of an application by means of visual tools, but with WPF you will soon be looking at XML/XAML code.
What’s worse is that it’s not just another language with some different syntax, but a language with a different paradigm. Functional languages are considered by some as the ultimate weapon for producing bug free code in a breeze, but most developers find imperative approaches quite a bit easier to read and extend. I believe XAML is a little like a functional language.
For example, variables are a simple and well understood concept in imperative languages. With XAML, it’s not always obvious how to reference an element from another element. The situation gets surprisingly complex when you add name scopes and cross assembly references to the mix.
You’ll often be tempted to switch back to C#, as in WPF you can always choose. But even simple extensions to XAML require a fairly large amount of boilerplate code. For example, converting values for display require a small class to be written (a converter), then you need to declare an instance of this in XAML, then reference the instance in the appropriate places. All of this is really a lot of burden when you might be applying a simple formula to the input.
Another situation where the code behind temptation will be strong is when dealing with animations. Animations seem like an imperative concept more than a declarative one (animations are sequences of steps after all) so it feels natural to subscribe to events and play pause animations from handlers. Due to how animations affect properties, this is often not so straightforward. Just check the number of questions about properties being stuck on values from animations on stackoverflow.
Conclusion #1: XAML is a new language with a different syntax and paradigm compared to C# and moving code between them is not simple, so be prepared to learn and evaluate on a case by case basis what should end up in XAML and what in C#.  To put it in other words, WPF with XAML is like climbing a tree with many branches, whereas c# developers are mostly used to linear code.

Concept overriding

As I suggest in another article, an object oriented library is like a little language extension in itself. When using an OOP library, no programmer is surprised to see new domain related classes and interfaces. New classes describe the new concepts and interfaces state how the concept link to each other and are used to build systems. What is surprising, and not in a good sense, is when a library introduces new classes for basic language concepts.
WPF does this pretty regularly, and the first example is properties. Fields and properties are a well known, basic OOP tool. WPF turns this all around with specific classes to represent values in user interface objects. There are of course good reasons for all of this, but the fact that a basic language concept becomes much more complex to use is baffling. It’s especially baffling as the minds behind this architecture could have chosen for a different approach based either on language extensions or more heavily relying on programming tools, as it’s all Microsoft products and technologies.
Notifications from non user interface classes to UI are moreover handled in yet another way, by means of the INotifiable interface. Simple properties in WPF thus turn either into complex dependency properties or into INotifiable properties.
Conclusion #2: WPF as a library has a steep learning curve as it redefines even basic programming concepts. As far as properties are concerned, use dependecy properties only for UI specific configuration properties, and use INotifiable properties for signaling data model changes to the UI.

Infrastructure rich vs. feature poor

WPF clearly provides a very rich infrastructure with the XAML declarative language for UI and many new concepts and classes to learn. It supports themes, animations, transparencies, data binding. More than a simple UI library, WPF is a complex, rich application development framework. On the other hand, considering what you get with WPF out of the box, the number of actual UI widgets and tools is rather limited. You might be surprised to see there’s no file open dialogs or any other standard dialogs. There’s no chart control of any kind, no graph, no bar plot or the likes. If you are looking for panels that automatically support touch based interaction with basic animations, you’ll find none. This lack of features is at the beginning quite disarming. You would expect to use additional UI libraries for advanced cases, but it feels like standard WPF controls don’t even cover the basic ones. Or they do so in such generic ways as to require a lot of work. The ItemsControl and its derivatives are examples of this uber-generality: any list of things fits the ItemsControl, be it an image gallery, a data grid, etc. This is great in a way, but it also means that the generic control does not exactly provide parameters to tune interactions for each specific case; when you want to customize the ItemsControl, you have to learn about the templating side of WPF. It’s a new way of extending a control, which is not based either on the familiar inheritance of a basic control type or on the composability of user controls. It’s not bad, it’s just yet another way of extending WPF.
Given the limited amount of controls, the other extension you might be interested in is to tweak the appearance or interaction of standard controls. For example, I needed to specify a different thumb for a slider control that was controlling the brightness of an image. Personally, I would have liked and expected a property on the control with a name like “ThumbIcon” or similar. Unfortunately, there’s nothing like that. What you need to do to make such simple tweak is to understand that WPF uses control templates to specify the visual appearance of any control (please note this a different type of template, not the data template used in the ItemsControl). This template can be extended, modified, or even completely replaced. In order to change the slider thumb as in my example, I had to update the control template. First of all, such control template is not immediately available in Visual Studio. After digging this template, I was confronted with a rather huge piece of XAML code that accounts for both vertical and horizontal sliders. Moreover, templates of built in controls are based on another WPF concept, the “parts and states” model. At the end of this experience, I was left with the feeling that writing my own slider from scratch would have been a lot easier. If you are creating simple controls that are used in well defined scenarios, consider whether you should really extend a built in control or rather write a more specific one from scratch.
Conclusion #3: you will not get a whole lot of controls with WPF. Be prepared to evaluate WPF control libraries, and be prepared to write at least some of the controls yourself.

Non linear-complexity decision paths

A last tricky point of WPF is that certain decisions might lead you in surprising dead ends. For example, you can create new controls either by composing controls, or by deriving from a basic control class. It seems like any of the two paths should be possible, with the second one possibly giving you more freedom to tweak the behavior of the control, whereas the first one is the easier route with more support from the visual editor. This might be true for a simple widget; if the control you are writing is a container control, the situation is different. Due to how WPF handles names, the difficult route is the one to take for containers or otherwise you won’t be able to use the container with named content. The fact is that it’s not straightforward to turn a composed control into a custom control; in the first case you have a XAML that specifies the concrete appearance of the control, in the second case you need to write a style, which is still XAML but with slightly different constraints. Turning a user control into a custom control is thus not just a matter of changing the base class name.

Conclusion #4: choosing the right starting point/class for using WPF might not be easy. Read the manuals before you start extending the wrong control.

No more piles on our desks, hurray!

Computers and mobile devices are made to support busy people who do a lot of activities at the same time. To be honest, I tried so many times to chat while developing but rarely succeeded to have both a polite conversation and an inspired coding attitude all at the same time. In reality both women (who areImage known to be more multitask-oriented) and men alike, when in front of a modern computer or mobile device, are most often attending true symphonies of concurrent software behaviors.

Panels and menus slide with buttery smooth animations in and out of view, glowing texts highlight stock exchange data that is grabbed from a service miles away, all the while pictures of your friends are being downloaded to the phone and hundreds other big and small things are happening.
Even when you are not that busy, you expect at least those buttery smooth animations from your mega-core phone. The first reason for the need of concurrency is thus the fact that, even with static data, user interface is expected to be very dynamic. If you move a window around and the other content stays fixed and gets hidden, users will get annoyed. Honestly, who thinks that the metaphor of a busy desk is a good starting point for organizing a user interface? I know that I am writing this post on a pc with such overlapping windows interface, but I never have overlapping windows in practice. I would much prefer to have my two-three open documents resize when I drag this window around. Modern, phone-like user interfaces are like that. They do the work for you, resize this, layout that, and your screen is always nice and tidy. No overlapping paperwork, no partially hidden stuff. I am amazed that the messy multi-layer desktop has turned into the big success it has been until now. I am very happy that the trend has shifted, but it’s not all roses for software engineers.
All this keeping tidy work is expensive in terms of computing resources, because it needs to be fast and super smooth not be distracting. Animations help the user when they are smooth, as animated UIs can more easily drive the attention to the right place, and they can show content without being too “abrupt”. All this real-time work means that even applications that are static, in the sense that their data content does not change (much) over time, show a lot of dynamic behaviors and thus require concurrent programming to be developed.

How to implement this?

Super smooth UIs require that all lengthy operations are delegated to background workers. The issue is that lengthy in this context is actually quite short and fast. An interface that hangs or hesitates for a few milliseconds is not perceived as smooth anymore. It might still be perfectly usable, but the feeling changes completely.  So whatever the application does which is not showing a blistering fast UI must be delegated to the background. Reading a file from a fast drive? probably fast enough for data retrieval, but surely not fast enough if this loading step interrupts a ui animation. Network communication? It’s unpredictable, never do it from the main application thread. Lengthy cpu processing follows the same faith of being delegated.
In old single threaded applications, even graphical user interface ones, the main thread which dealt with the UI was also running the business logic. In modern applications, the main (UI) thread does nothign but gathering input from the user, dispatching that input, and requesting user interface controls to repaint. The message is clear: modern application development requires good parallel programming attitudes. This is especially true because of another reason apart from animations and smooth UIs. The average user does not have three documents overlapping one another on screen, and probably focuses on one-two applications max, but still expects the one-two applications on screen to show all content that is required without flipping through pages and pages of interface. Those two-three panels in the app should show all content that is relevant. Maybe it’s not MDI (multiple documents interfaces), but often large screens are expected to be filled with MDVI (multiple data views interfaces). Handling updates to the different views of data require again a good dose of parallelism. I really like this trend of lean and mean for the user, pushing the organizational work to the side of the application. As to the actual technical choices of parallelization techniques, there are many articles, books and posts around. It’s a topic I really like, so I’ll probably post about it soon.