As I've been neck-deep in Silverlight 2 for a couple of months now I noticed that there are some bugs/inconsistencies that aren't necessarily known to everyone. Here's a list of some of the issues (with workarounds if possible):
Custom Control Data Binding
If you are writing User/Custom Controls that want to be used in data binding (i.e. DataTemplate), you must use the assembly name in the namespace declaration, even if it is in the main assembly:
Bad:
xmlns:my="clr-namespace:MyAssembly.Controls"
Good:
xmlns:my="clr-namespace:MyAssembly.Controls;assembly=MyAssembly"
This is a known bug that will be fixed in future builds.
Uri Issues
In Silverlight 2 (in contrast to previous versions) the assets are packaged up in a .xap file. This .xap file is simply a ZIP file that contains the assemblies and other assets. In this file you can have images, fonts and other assets required. This new facility has made Uri's a bit confusing. When you specify a relative Uri in your Silverlight 2 project it may mean inside the .xap file or it may mean from the server.
The key is that relative Uri's will first look in the .xap file then look on the server but this isn't universal. For example if you have a foo.jpg in the root of your .xap file and specify this Image tag, it will find it in the .xap file:
If the foo.jpg doesn't exist in the .xap, Silverlight 2 will look at the server for the file (most of the time)...but where is it looking? Unlike what you might expect, it actually looks on the file server relative to the ClientBin directory (where the .xap file is loaded from). If you want to have an image file loaded from the /image folder of the web server you would specify:
This works because it is relative to the ClientBin directory. If you specify "/images/foo.jpg" it won't look on the server. This is the bug. Using a full path to the server fixes this but that is fragile (you need to change it when you deploy an application).
This is especially an issue with MediaElement as it doesn't seem to work at all with relative paths. Interestingly if you look at the Uri usage with Reflector, the Source property in the MediaElement strip off the Uri and just send it the plain string (again, this is what I consider a bug). So if you're using a MediaElement, use non-relative paths for the Source.
In general I have found different/buggy behavior with different controls so if you are having trouble with Uri's, go to non-relative Uri's (e.g. full paths).
Using the Silverlight Control
If you want to use the ASP.NET Silverlight Control it requires ASP.NET AJAX 3.5. It requires a ScriptManager on the page and only works with the 3.5 version of AJAX. This means that if you are not using AJAX 3.5 you will need to use one of the other methods:
- Silverlight.js
- Object tag
I tend to like the Silverlight.js for deployed projects anyway because of the additional functionality of Silverlight.isInstalled and other small features. If you used Silverlight 1.0 you'll already be familiar with Silverlight.js. The version that ships with Silverlight 2 has been updated to support Silvelright 2 deployment.
ImageBrush Can't Be Data Bound
This is a small but pesky bug that if you try to use data binding with the Image brush it just fails (or locks up the browser). So if you want to set the ImageBrush, you'll need to wrap a UserControl and data bind a DependencyProperty that will set the ImageBrush manually. Not hard but just a workaround.
LINQ Projections or Anonymous Types Fail on Data Binding
If you are using LINQ to do projections or using Anonymous types, data binding gets confused and tends to lock up the browser. For example:
var qry = from x in customers
select new
{
Name = x.CustomerName,
Phone = x.ContactPhone
};
theList.ItemsSource = qry.ToList();
The alternative is to just select the entire object (or use static types instead of anonymous types).
Popup.DataContext Doesn't Work
If you are using the cool Popup element and you want to use Data Binding to fill in data, the DataContext of the Popup fails to propogate its container. Therefore you need to manually set the first child's DataContext instead:
That's all for the issues that I am working around these days. If you have more, feel free to drop them in the comments!
Add Comment | digg this