This is a true story. It’s a story about porting a non-trivial WPF application, NHProf, to Silverlight 4. The story begins today with my first actual work on the porting process. Microsoft has been preaching how easy it is to move between these platforms. Are they telling the truth? I’ll (try to) let you be the judge. I’ve been a bit lax in my blogging lately, but I’m going to try and give a semi-regular account of my progress on this port along with the challenges I meet along the way. Perhaps I’ll be able to offer some meaningful workarounds that others can use; perhaps not. Maybe, dear reader, you can recommend some solutions to me.
Today I spent about 6 hours on the Silverlight version of NHProf. I basically did a File->New Project and began moving small pieces of the application shell over to Silverlight. The new application is not much to see at this point…most of the UI is missing entirely.
Below is a summary of the platform inconsistencies I came across in the first six hours of work:
- Xmlns – Silverlight 4 allows assemblies to define custom Uri-based Xml namespaces. Unfortunately, Microsoft has done a rather poor job of using this feature themselves. The first issue I came up against today was related to this. It’s not a big problem, but rather an annoyance. The reason is that some controls are in different assmelbies/namespaces in Silverlight than in WPF. Take DockPanel, for example. It’s a core Panel in WPF, but not in Silverlight. Microsoft hasn’t patched up the namespaces for this, so if you port code using DockPanel, you have to go add custom xmlns everythwere. Yuck. This is true of everything in the Silverlight Toolkit. It would be really nice if they took everything in the SDK and everything in the Toolkit and just put them in the default namespace. Unfortunately, this one issue is probably going to prevent a direct reuse of any of our views.
- TabControl – If you have seen the NHProf UI, It’s fairly obvious that we rely heavily on the TabControl. Unfortunately, the Silverlight TabControl is completely broken for data binding. Furthermore, it doesn’t have all the necessary template properties either. Basically, it’s completely different from the WPF version and completely unusable if you are using an MVVM architecture. My work around has been to use a horizontal ListBox for the “tabs” and a ContentControl for the “SelectedItem,” then rely on styling to make it look like a tab control. You can see this in the screenshot above (minus the styling of coarse).
- ToolTip vs. ToolTipService – In WPF, every control has a ToolTip property; not so in Silverlight. You have to use an attached property called ToolTipService.ToolTip instead. Again, not a big problem, but it forces me to change every view.
- Grid.IsSharedSizeScope and ColumnDefinition.SharedSizeGroup – Missing. There’s no way I know of to do a shared size scope layout in Silverlight. We used this quite a bit in the WPF version. Most of our “data grids” are actually list boxes with shared size scope layout. It was just simpler and more light weight. To solve this, I’m actually using the Sivlerlight DataGrid control. You can see it in the screen shot above displaying the Session Statistics. Ultimately, I think this will be an improvement to the UI. It just seams a bit heavy-weight considering that all of our grids are readonly. Suggestions?
- ItemsControl.AlternationCount – Missing. This was primarily used in the style to generate alternating row colors. Since most of our ItemsControls/ListBoxes are going to be switched to DataGrid, this probably won’t be a big deal in the end. Still, I’d be interested in knowing what the proper way to do alternating row styles in Silverlight is.
- TextTrimming="CharacterEllipsis" – Missing. We just have to go with WordEllipsis or roll our own ;(
- DynamicResource – Missing. I’ve temporarily removed all the styles for the views I have ported. I’m really not sure what the ramifications of the missing DynamicResource will be in the end.
- HeaderedContentControl Template uses a StackPanel – The HeaderedItemsControl’s template is built wrong…Period. It uses a StackPanel for layout and that prevents styling the control to expand properly. It should use a DockPanel. As I mentioned above, DockPanel is not in the core, which is probably why the HeaderedItemsControl is broken. Now, if they would just move the DockPanel….
- ContextMenu – Missing. Silverlight offers mouse right-click support, but no ContextMenu out of the box. We are going to have to build this one from scratch.
- DispatcherTimer(DispatcherPriority.Normal) – There’s no notion of DispatcherPriority in silverlight! So usage of the Dispatcher and DispatcherTimer can be quite different. Unfortunately, I won’t know the full effect of this until we start pushing lots of data through this thing…I don’t think it will be a problem. But, when it comes to SL vs. WPF, I’ve learned not to take anything for granted.
- RegexOptions.Compiled – Missing. We’ll just have to do without that.
- String.StartsWith - Missing overload for culture. Created an extension method as workaround.
- StringBuilder - Missing overload to insert a character. Created an extension method as workaround.
- DateTimeFormatInfo - Missing GetAllDateTimePatterns. Created an extension method as workaround. Faked the implementation…
Hmm. That’s a bit disconcerting for a mere six hours in. What’s interesting to note are the the differences in core APIs. I expected the graphics stack to have some inconsistencies, but I didn’t expect to hit BCL differences so quickly. I also expected to get a lot more of the shell done today. Looking at the screenshot above….I’m a bit embarrassed at the lack of progress. So far, porting WPF to Silverlight is slow going.
03-25-2010 4:33 PM
Filed under: Xaml, databinding, Control Templates, WPF/e, .NET 3.5, Caliburn, Featured, Silverlight, NHibernate, MVVM, UI Architecture, NHProf