After some initial struggles with Authentication Services and cookies in WCF it turned out porting the Dive Log Silverlight application to WPF was fairly straight forward. Once I had figured out how to authenticate from WPF it didn’t take more than a few hours to bring the entire application over from Silverlight. I’ll list some of the gotchas I ran into while porting the code
The Silverlight version is protected using Forms Authentication and an ASP.NET membership provider. The WPF version uses WCF authentication services, and needs to manage the authentication cookie manually. Details about this are covered in post I did this weekend. After figuring out how handle authentication implementing the login screen was straight forward. It uses the same Model-View-ViewModel design as the rest of the application.
Presentation Models (ViewModel)
The Dive Log uses Presentation Model pattern (aka Model-View-ViewModel in WPF/Silverlight circles), so the majority of the application code is non-visual. I was able to port that code straight over to WPF with some minor adjustment. The WPF version has an extra dependency to a cookie manager (that’s how the Dive Log service gets the authentication cookie from the login service). I also had to change the event handlers for the commands.
In WPF commands are built into the framework so I could throw away some of the code from the Silverlight version. The command implementation used in the Silverlight application is very similar to the WPF commands, so porting the code wasn’t a big challenge.
Value Converters is the Swiss army knife of WPF and Silverlight programming. It lets you convert pieces of data during data binding. The Dive Log application has 8 value converters and I was able to port all of them straight to WPF with no code change.
IoC and Dependency Injection
The application uses Ninject for dependency injection. Ninject supports both Silverlight and WPF so I could reuse all that code. I had to make some changes in the configuration class. In Silverlight I use the HtmlPage.IsEnabled property to check if the code is consumed by Blend. In WPF you got a IsInDesignModeProperty dependency property you can use to check if the code is consumed by Blend or Cider.
The “basic” user interface version
The Dive Log application comes with two user interfaces, one done by a developer, one done with the help of a designer. The simple UI version ported nicely over to WPF, with a few minor changes. The first thing I had to change is that WPF supports Windows, while the top level element in Silverlight is a user control. Silverlight also got a couple of controls currently not available in WPF. One of these is the date time picker. In the WPF version I used a simple textbox instead. Other than that the UI pretty much just worked out of the box. It looked a little different since some of the default styles for some of the controls are a little different.
The “full” user interface version
The richer version of the user interface contains several template controls and I didn’t expect to be able to reuse a lot of the XAML. But since the styles and templates are defined as resources I was still able to copy-paste the skeleton of the UI with only a couple minor changes. The screen shot below shows the WPF version after a rough copy-paste. The problem with porting the UI is that Silverlight uses the Visual State Manager for styling and templates, while WPF uses triggers. So for this part of the application I had to do a lot of hand coding of the XAML, moving each template over piece by piece. I was still able to reuse a lot of the individual pieces, such as the XAML graphics used for the weather check boxes, the customized slider control, and some of the other graphical elements.
The Dive Log application is a fairly trivial application, yet complex enough to give a decent indication of what it would take to port an application from Silverlight to WPF. I was pleasantly surprised with how easy it was to port the application to WPF. However you will have to do some manual work, especially around styled controls. Patterns like the Model-View-ViewModel pattern make it easy to reuse your ViewModel classes between WPF and Silverlight, and code-only elements such as value converters ports straight over to WPF. But I think the biggest thing you gain from working with both Silverlight and WPF is reuse of skills. With little WPF knowledge I was able to build a fairly rich application using what I know from working with Blend 2.5 and Silverlight, which is huge! I’ve uploaded the current source code, as well as a compiled version of the WPF application if you want to try it. They’re available as embedded downloads from Windows Live Sky Drive (might not be visible in your RSS reader).