Windows Store-apps: WinRT XAML vs. Silverlight XAML

This post is part of a series about creating Windows Store-apps with XAML and C#. Find the Content of the series here: Windows Store-apps with XAML and C# blog-series Last weekend I’ve finished the XAML-chapter of my upcoming book about developing Windows Store-apps with XAML and C#. I want to share the things that you should know about the WinRT XAML – the way I call it here - if you’re familiar with Silverlight or WPF. The WinRT XAML is much like the XAML we know from Silverlight. But there are some differences in WinRT XAML:
  • the way you use your custom namespaces is different
  • there are some missing things (TypeConverters, Custom MarkupExtensions)
Let’s look at the two parts

Use custom namespaces

There are two ways in XAML to use a namespace:
  • 1:1-Namespace-Mapping
  • 1:n-Namespace-Mapping
Read the difference for both in Silverlight- and WinRT-XAML below.

The 1:1-Namespace-Mapping

Let’s assume you’ve the following class:
namespace UIRocker.Special
{
  public class WindowsEight
  {
    public bool IsGreat { get; set; }
  }
}
To use this class in Silverlight-XAML, you’ve to add an Namespace-Mapping like this
xmlns:rocker="clr-namespace:UIRocker.Special"
or like this if the CLR-Namespace is in another assembly than the XAML-file containing the Namespace-Mapping below: 
xmlns:rocker="clr-namespace:UIRocker.Special; assembly=UIRockerLib"
With the Namespace-Mapping the classes from that Namespaces can be used with the chosen alias. The alias is “rocker” in the snippets above, so the WindowsEight-class can be used as below:
<rocker:WindowsEight IsGreat="True"/>
In WinRT-XAML you’re using the class in the same way as above, but the way of creating the Namespace-Mapping is different. Instead of using the syntax with “clr-namespace…” you use:
xmlns:rocker="using:UIRocker.Special"
You don’t care if the Namespace UIRocker.Special is in another assembly as the XAML-file or not. This works exactly the same way as the using-directive in C#, where you also don’t care if the Namespace is in another assembly than the .cs-File or not. So, great improvement, but creates a little incompability with Silverlight-XAML.

The 1:n-Namespace-Mapping with XmlnsDefinition-Attribute

The Namespace-Mappings above have been 1:1-Mappings. One XML-Namespace was mapped to one Silverlight/WinRT-Namespace. In Silverlight-XAML you can create a 1:n-Namespace-Mapping by placing the XmlnsDefinitionAttribute (Namespace: System.Windows.Markup) on your assemblies like this:
[assembly: XmlnsDefinition(
 "http://thomasclaudiushuber.com/","UIRocker.Special")]
[assembly: XmlnsDefinition(
  "http://thomasclaudiushuber.com/", "UIRocker.Mvvm")]
Classes out of the Namespaces UIRocker.Special and UIRocker.Mvvm can be used in XAML with one alias by making a 1:n-Namespace-Mapping like this:
xmlns:rocker="http://thomasclaudiushuber.com/"
Unfortunately in WinRT-XAML there is no possibility for a 1:n-Mapping. The Namespace Windows.UI.Xaml.Markup contains a XmlnsDefinition, but it’s not an attribute, it’s a struct and therefore not usable. Especially when you create a library with many Namespaces in it, it’s great to use just one alias for the library in XAML. Maybe the next Version of WinRT will contain such a mapping. By the way, first versions of Silverlight also didn’t support 1:n-Namespace-Mappings.

Missing things in WinRT-XAML

There are a few other things that are not in WinRT-XAML or behave differently. Let’s take a look at them.

Typeconverters

As XAML is XML, every Attribute contains a string-value. This string-value needs to be converted into the value of the property-type the attribute represents. For primitive types like double, float, int, bool, char etc., the conversion automatically is done by the XAML-Parser (Silverlight and WinRT). Also for Properties of type enum, the XAML-Parser tries to convert the specified string-value into the enum-type of the property. There is also a conversion for some central types hardcoded in the XAML-Parser of Silverlight and WinRT, e.g. the Brush-Type. This conversion allows you to assign a string in XAML where a Brush-Instance is required:
<ListBox Background="Red">
The XAML-Parser takes the “Red”-string, creates a SolidColorBrush with the Color Red and assigns it to the Background-property of the ListBox. (Excourse to WPF-XAML: In WPF-XAML this conversion is not done by the XAML-Parser, it is done by the BrushConverter-class) Now if you have properties that are of your own type, let’s look at this works in Silverlight and WinRT. Let’s assume we have the classes below:
public class Person
{
  public Address Address { get; set; }
}
public class Address
{
  public string City { get; set; }
  public string Country { get; set; }
}
In Silverlight-XAML, it is possible to create a Person-instance as below if a TypeConverter for the Address-type exists:
<local:Person Address="Müllheim Germany"/>
The corresponding typeconverter could look like this:
public class AddressConverter : TypeConverter
{
  public override bool CanConvertFrom(...Type sourceType)
  {
    if (sourceType == typeof(string))
      return true;
    return base.CanConvertFrom(context, sourceType);
  }
  public override object ConvertFrom(...object value)
  {
    if (value != null && value is string)
    {
      var array = value.ToString().Split(' ');
      if (array.Length != 2)
        throw new ArgumentOutOfRangeException(
          "Invalid format for address");
      return new Address
      {
        City = array[0],
        Country = array[0]
      };
    }
    return base.ConvertFrom(value);
  }
}
The only thing that is additionally required is to tell the XAML-Parser where to find the AddressConverter. You do this by specifying the TypeConverterAttribute either on the Address-Property in the Person-class or on the Address-class itself. Below an example that specifies it on the Address-class.
public class Person
{
  public Address Address { get; set; }
}
[TypeConverter(typeof(AddressConverter))]
public class Address
{
  public string City { get; set; }
  public string Country { get; set; }
}
So far to Silverlight-XAML, now let’s look at WinRT-XAML. As mentioned above, WinRT-XAML also supports conversion for
  • primitive Types like bool, char, double, int, float,…
  • enumeration-values
  • central types like e.g. the Brush-type.
If you’ve custom types like the Address-class, currently there’s no support. There’s no TypeConverter in WinRT. Dot.

Markup-Extensions

In Silverlight-XAML it’s possible to create custom subclasses from MarkupExtension and use them in XAML with curly braces. WinRT doesn’t support custom Markup-Extensions. Dot. Did you find out other bigger differences about XAML? See you next week with the next post about WinRT and Windows Store-apps. Thomas
Read more...

Windows Store-apps with XAML and C# – blog series

Since yesterday evening Winodws 8 RTM is out for developers. This blogpost is the start of a blog-series about developing Windows Store-apps with XAML and C#. The series consists of some informational and some “how-to” posts: More topics will come. If you’ve topics not listed above you want to read about, write a comment on this post. The first post about XAML will be written till saturday evening Thomas
Read more...