A while ago, I wrote a very positive (NOT) blog about my first steps with Silverlight. Since I didn’t want to make the post too long, I decided to stop at 10 points. Now, I think it’s time to write the next article with a new list of things I really hope they will fix in Silverlight.
First things first: the point of these articles is not to bash Silverlight continuously. It’s to reveal the “bad things” of Silverlight. If it really sucked, I wouldn’t even be writing this article right now. Ok, up to the flaws now, the list is long enough.
I wanted to hide a control (but keep all the existing controls in place). Do you think there is a Visibility.Hidden in Silverlight? Of course not, you can either choose for Visibility.Visible or Visibility.Collapsed. If you want to hide a control, set it’s opacity to 0. Oh, and don’t forget to disable the hit test as well, otherwise you can still interact with the invisible control.
When porting Catel, I wanted to port as much converters as possible. Most of them are WPF and Silverlight compatible. But, when a converter is not able to convert a value back, you should return Binding.DoNothing according to the documentation. What seems, Silverlight doesn’t have this, so I have to return DependencyProperty.UnsetValue. Now I had to create this class to prevent myself from writing this code everywhere:
/// <summary>
/// Converter helper class.
/// </summary>
public static class ConverterHelper
{
/// <summary>
/// The generic <c>DoNothing</c> value, compatible with WPF and Silverlight.
/// </summary>
public static readonly object DoNothingBindingValue =
#if SILVERLIGHT
DependencyProperty.UnsetValue;
#else
Binding.DoNothing;
#endif
}
In Catel, we also have a lot of unit tests to make sure that we don’t break functionality. One of the things we test is the PropertyHelper class that helps us setting and getting properties via reflection. In the .NET Framework, you can set a property with a private setter via PropertyInfo.SetValue. In Silverlight this is not possible. I agree with the Silverlight team to prevent it, but there are several reasons they should not have implemented it this way:
- Microsoft keeps telling us that Silverlight is part of the .NET Framework, or at least I got that feeling, so keep functionality the same.
- Don’t set PropertyInfo.CanWrite to true if we can’t!
I think Microsoft should really use the same unit tests for Silverlight and the .NET Framework, especially for shared libraries.
Then, you also want to know the version of your assembly, right? In the .NET Framework, one can use the Assembly.GetName() method. In Silverlight, this method is public as well, but it’s not accessible! You get a security exception (or something like that) as soon as you call the method because it’s flagged to be used by Microsoft only. Then make it internal!
Last but not least, this is one of the issues that bothers me the most. Exceptions are a great way to solve issues simply because you can log all information and then solve issues in your code (or just ignore them). A few unit tests that I wrote checked if the right exception was thrown (ArgumentNullException) for the right argument. What seems, the ArgumentNullException does not provide the ParamName property. In other words, good luck finding out which parameter was null. Happy puzzling!
Summary of issues I walked into
- No Visibility.Hidden
- No Binding.DoNothing
- PropertyInfo.GetValue and PropertyInfo.SetValue behave differently from .NET
- No Assembly.GetName()
- ArgumentNullException has no ParamName