Friday, October 17, 2008

XAML Integrator

XAML represents a bridge between the designer and developer teams.
A new role has emerged as the result of this fusion, that Paul Alexander, a technical program manager with IdentityMine, calls the integrator:

"The Integrator understands the needs of the developer while also supporting the needs of the designer to assure that the app's UI is as compelling as it was designed, while also validating that the concepts can be realized in code from the developer."
The integrator deals mostly with XAML code and provides an interface between the developer and designer, by structuring and modularizing the XAML.

Therefore, the ideal integrator must posess strong design skills and a thorough understanding of XAML and Windows Presentation Foundation (WPF) concepts such as inheritance, styles, and resource lookup.

The Designer -> Integrator -> Developer Model allows the design team to leave the XAML unattended and focus on having their assets effectively integrated into the project.
Designers can work with tools such as Expression Design, Inkscape or Adobe Illustrator and output the results as XAML.
The integrator then integrates the XAML into the project and passes it on to the developers, who need not to be concerned with design issues.
Obviously, this model also works perfectly well the other way around, and in some cases it is advisable to have the developer team establish the foundations of the project.

A recently released tool by Microsoft, Expression Blend, makes this transition even easier, by accepting and generating XAML code that can be directly imported/exported from/to Visual Studio.

1 comment:

Anonymous said...

... you can define your UI in a main assembly (for example the EXE), but define all the UI ressources (Templates, Brushes, Styles, etc...) in a ResourceDictionary located in another DLL. WPF allows "importing" resources defined in an external DLL using the following syntax:
--ResourceDictionary Source="/Skins;component/Dictionary1.xaml"/--

This special syntax is called "pack URI", and allows to link in a very flexible way to files located in an assembly (local or external), to a file on the hard disk, or even to a file on the server.

Once the resources have been "imported", you can use them in your code with:
-- Button Template="{StaticResource ButtonControlTemplate1}" /--

This is very nice, because it's a real physical decoupling of content (the code and its behaviour) and look&feel. Later, if you want to change the way your application looks, but don't want to modify anything in the code-behind, you can edit the "Skins" DLL in Expression Blend, and replace the original Skins.DLL with the new one. The next time the application runs, the changes will appear magically. Additionally, you can move resources around without changing your XAML code, you only have to load the right file in the parent's resources (containing element, window, application...).

However, Blend 1 made this scenario a little difficult, because it had difficulties resolving resources located in external assemblies. Blend 2 improved a lot, but you need to be careful when you include the external resource dictionary in your control's resources. Here is a check-list which will allow you to use Blend 2 at its full power with external resources:

(note: this checklist is for Visual Studio 2005 and Expression Blend 2. It's slightly different in Visual Studio 2008, but is easy enough to map)
Create a new WPF application in Visual Studio 2005
"File / New / Project / NET Framework 3.0 / Windows Application (WPF)". Name the project "MyApplication"
In the Solution Explorer, right-click on the solution and select "Add / New project / Custom Control Library (WPF)". Name this project "Skins".
Select the UserControl1.xaml and delete it. This deletes both the XAML file and the C# file (code-behind).
Right-click on the Skins project and select "Add / Resource Dictionary". Keep the name Dictionary1.xaml.
Right click on the project MyApplication and select "Add reference / (wait, wait) / Projects / Skins". This creates a one-direction link between the Skins project and the MyApplication project.
Open the file Window1.xaml in the MyApplication project. Modify the XAML code to look this way:
--Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="MyApplication.Window1" Title="Window1" Height="300" Width="300" -- --Window.Resources-- --ResourceDictionary-- --ResourceDictionary.MergedDictionaries-- --ResourceDictionary Source="/Skins;component/Dictionary1.xaml"/-- --/ResourceDictionary.MergedDictionaries> --/ResourceDictionary-- --/Window.Resources-- --Grid-- --/Grid-- --/Window--

This imports the resources defined in Dictionary1.xaml, in the external assembly, so that they will be parsed and made available to your controls.
Save everything, Build once to create the assemblies.

Now we will change to Expression Blend 2 and store a resource in the external Dictionary1.xaml
Open the solution in Expression Blend 2.
Open the file Window1.xaml.
Add a Button to the Window using the toolbar on the left

Make sure that the Selection tool is selected in the toolbox. Right-click on the button and select "Edit Control Parts (Template) / Create Empty".
This opens a dialog. Note how you can choose to store the new template in the resource dictionary "Dictionary1.xaml" even though it is located in an external assembly.


This makes working with external resources in Blend a real pleasure!

Note: You can also include Dictionary1's resources in your window using the following syntax:
--Window.Resources-- --ResourceDictionary Source="/Skins;component/Dictionary1.xaml"/-- --/Window.Resources--

However, while your application will actually find the resources and run correctly, Blend will not be able to resolve them. It is therefore important to use the syntax I describe further above to make sure that Blend runs fine!