A new role
It's hard to believe, but it's true, it has been already one week since I came back from MIX. During this week, I have been so busy with the project that I didn't even have time to blog.
In the project we are currently developing, one of my roles is to be WPF integrator. This is a new role that has been discussed already quite a lot in various occasions. The WPF integrator stands between the designers and the developers. His role is to coordinate the work between these two very different worlds, and to try to get everyone understand each other. Honestly, there is more to this role than just that, but so far it's been pretty much the major challenge :-)
Designers in the traditional UI world are used to design screens, to count pixels and to produce amazing look&feels that the developers will later mess up in the implementation. WPF introduces a very new way of designing, because designers now have the chance to work on real code, on what we call XAML assets, or "pieces of codes" that the integrator uses as is in the application.
People like Scott Guthrie, Robby Ingebretsen, Nathan Dunlap and many others spent a lot of time thinking and talking about the new designer-developer workflow. A lot of things have been told about that at MIX. Check the sessions
for more info.
After a few weeks spent in this role, I believe that there are various ways to do WPF. In our current configuration, we have quite a few teams of developers (though in the moment only 3 of them are actually developing WPF, this number will grow soon), and one team of designers. The various challenges I face are:
Different understanding of the deliverables: That's no doubts the major challenge. Due to their previous experience, managers have a hard time understanding that WPF requests different deliverables than in the past. Even though their designers (and especially those coming from web design, where the workflow is not that different from WPF) know what the integrator needs, often they face misunderstanding from their hierarchy. Let's make one thing clear: Now's not the time to spend hours speciyfing pixels and shades of blue. We can concentrate on that later, on the real application, when it's working. For the moment, we need functionality (does that sound like a rant against management? well, it should).
Time difference: Our designers are in a very different time zone than the 3 teams currently implementing. The integrator must have a lot of flexibility and very strange working hours.
Getting the developers to let go: Once again an education challenge. The developers coming from more traditional programming models (MFC, WinForms...) have a hard time understanding and accepting that they must let go of the design, and concentrate on the funcitonality. A few times, I had to simply select-all and delete huge chunks of XAML, because they were simply to be replaced by the real thing. Developers, get used to it, that's not your responsibility anymore!
I want to moderate a little that last statement: We are talking about roles here. In smaller projects, the same person can very well have both roles of designer and developer. In that configuration, an integrator is not needed :-) So it's actually still useful for developers to learn and understand XAML!
One thing I discovered this week is the difficulty to keep a complex application blendable.
(By this we mean: Keeping an application's code so that the project can be opened and reworked in Expression Blend).
Let's be clear: For the moment our application is not blendable. I can see pieces of it in Blend, but not enough to actually allow the designers to work on it. I think it's a problem that we should work on. We have a few issues here:
The application needs data coming from an underlying service. For various reasons, there is no way to get this service to work in Blend (interoperability problems). So a lot of data is simply not available in Blend, and thus the corresponding data binding and data templates are not rendered correctly. Maybe this could be solved by a simulation layer, but I am not sure if (a) it's doable at all in our case and (b) the additional amount of work is really worth it.
We work a lot with user controls, which are then dynamically loaded in the application. These user controls don't have a "life on their own", for example they don't have a dimension, but their height and width are set to Auto. When you edit such a user control in Blend, it's very hard to work on it, for example to modify a background. To solve this for the moment, I temporarily set a width and height in pixels on the user control, edit the background, and then revert to Auto. That's not very handy, and I don't want the designers to have to do this.
We introduced a separation between the user control's code and its resources. The resource dictionaries the designers (or the integrator) are working on are in a separate DLL. When a change is introduced in this DLL, it must be recompiled for the result to be visible in the user control opened in Blend.
Our user controls do not inherit from System.Windows.Controls.UserControl, but from an intermediate abstract base class. We introduced this in order to be able to store functionality common to all the user controls in one place, and to make such functionality available automatically to all the instances. While this sounds like a good idea from a developer perspective, Blend is unable to open the user control, because it doesn't understand how to render that intermediate abstract class.
I don't lose hope totally that we'll be able to have a blendable application some day, but for the moment, I need another way to work with the designers. The solution we currently use is have the designers (or the integrator) work on templates (data template, control template).
For example, my designers created quite a complex background for one of our windows. This background is very elaborate. It has a linear gradient brush as its basis, then a shadow, and then a highlight. It looks great, but how to do a brush with all that? (WPF controls backgrounds are an instance of Brush, for example DrawingBrush, LinearGradientBrush, etc...).
To solve that issue, I created a control template for a Border, which is actually made of 3 rectangles on top of each other. Since WPF supports transparency natively, it's easy to reproduce the layering used in Expression Design by simply superposing the 3 rectangles. Using template binding, you can set each rectangle's width and height to be the same as the Border they will represent.
Then, in the actual user control, I place a Border under all other controls, and I set the Border's template to be the resource created before (the one with the 3 rectangles).
described pretty much that very same way of working in a recent blog entry. The only difference is that in my case, I don't use a ContentPresenter on the template I create, but I simply place the "background panel" under all the others. This is possible because we use a Grid as our layout root, and Grid supports z-index.
So now what?
Last week we just delivered an important baseline, and it looks quite good. I am a bit unsure about changes that need to be made to it to ensure maintainability and easier changes to the design, but I believe that we have a good basis to build on. In the next weeks, I want to institutionalize the use of templates for our assets (this is a minor refactoring of the application, just moving a few lines of XAML code around), and would like to have the designers work on that code too. We will also continue to integrate assets (icons, logos) as we receive them.