Many Silverlight developers (myself included) have found out the hard way that applications that use XamlReader.Load often don’t work on PCs in Europe and other parts of the world. I blogged about this a couple of weeks ago but had some erroneous information in my blog entry. I have since conducted more rigorous testing and also consulted with the folks on the Silverlight team that own the XAML parser. It’s time to set the record straight once and for all on XamlReader.Load, and make sure you know how to call it such that it works anywhere, on any PC, no matter the host’s PC’s regional and language settings.

For starters, consider the following call to XamlReader.Load, which will work on any PC, regardless of regional and language settings:

XamlReader.Load(“<Ellipse Width=”300.5″ Height=”200″ Fill=”Red” xmlns=”http://schemas.microsoft.com/client/2007″ />”);

Now check out this call to XamlReader.Load, which ostensibly does the same thing but fails on many non-US PCs:

XamlReader.Load(String.Format(“<Ellipse Width=”{0}” Height=”200″ Fill=”Red” xmlns=”http://schemas.microsoft.com/client/2007″ />”, 300.5)); 

To see for yourself, change your PC’s regional and language options format to “French (France)” and execute the call to XamlReader.Load. You’ll be met with an exception containing the following error message:

“Invalid attribute value 300,5 for property Width”

The problem is that XamlReader.Load expects culture-invariant strings to be passed to it. Among other things, this means decimal values need to be formatted with periods instead of commas. But on a PC configured to format numbers, currency values, and other values as the French do it, String.Format formats 300.5 as 300,5. XamlReader.Load doesn’t know what to do with such a string, so it throws an exception.

The solution is simple. If you use String.Format to generate strings passed to XamlReader.Load, and if String.Format’s output includes decimal values, pass a CultureInfo object referencing the invariant culture to String.Format:

XamlReader.Load(String.Format(CultureInfo.InvariantCulture, “<Ellipse Width=”{0}” Height=”200″ Fill=”Red” xmlns=”http://schemas.microsoft.com/client/2007″ />”, 300.5));

This ensures that 300.5 is formatted 300.5, and that XamlReader.Load will work regardless of how the PC on which it is executed is configured.