Single Sourcing WPF and Silverlight

by StefanOlson 27. November 2008 07:32

If you are like me, when you first heard about Silverlight, you thought this is fantastic, the WPF application you just developed can be taken, and with a few changes to support asynchronous loading, you've got an Internet accessible application! Well, think again!  That's not how it works.  Although it is supposed to be a subset of WPF, there is a lot of core WPF functionality that is either not there or operates fundamentally differently under Silverlight.

Most Microsoft people recommend that if you are starting a new application that you develop the Silverlight version first, and later move that to WPF.  Unfortunately, in our case we had already developed the Virtual Tour Viewer software for WPF, well before Silverlight was on the scene.  To some extent I still think it's better start with WPF because ultimately, hopefully, Silverlight will pick up more WPF functionality, and in my opinion the WPF functionality, such as triggers, is generally easier to code with than Silverlight equivalents.

To prove that it is possible, below are images of our virtual tour viewer running in WPF and Silverlight:

WPF

Silverlight

wpftour sltour

So, having built your application how do you convert it to Silverlight?  Well, the first thing is to create a new solution.  I have one solution for the Silverlight version and another one for the WPF version.  So I ended up with a folder structure like this:

 tourfolders

The Virtual Tour Viewer folder is the WPF version.  Within each solution the projects are replicated, with Silverlight versions and WPF versions of the project (where appropriate, there is some projects that are only in WPF in the Virtual Tour Viewer).  This can be seen below:

WPF

Silverlight

wpfprojects slprojects

So, what code can you share between Silverlight and WPF?  Initially, I was hopeful of being able to share both the xaml and .cs files.  However it became clear very early on that it was not going to be possible due to the number of differences in the xaml capabilities between Silverlight and WPF.  In the end there was not a single XAML file that I was able to share.  A number of people have also reported difficulties in dealing with linked XAML files in Visual Studio, although in my testing I did manage to get it to work, but I didn't do any serious testing so that may have been a fluke.

So in the end I share the code behind .cs files but not the XAML files.  I am also able to share all the data access layer .cs files.

The one important point is that you need to make sure that each assembly has exactly the same name on WPF and Silverlight.  This is important for xaml references

e.g:

xmlns:Controls1="clr-namespace:OlsonSoftware.Windows.Controls;assembly=OlsClassLibUI"

This reference can then be used across both WPF and Silverlight if the assembly name is kept the same. This can be done by right clicking on the project and selecting properties:

assemblyname

There are two ways you can manage each project:

Both projects in a single folder

This is the simplest way.  All you do is create a second project (in my case a Silverlight class library), in the same folder.  Visual Studio automatically sees all the files in that folder and you can simply exclude or include any files to get the files you require. 

incinprj

A problem with this approach is that it doesn't work where you have custom controls.  The xaml for a custom control is stored in a file called themes/generic.xaml.  Because your xaml will almost inevitably be different between WPF and Silverlight, it isn't possible to share that file between the two projects when they are both in the same folder, as you need two separate generic.xaml files. 

Another problem is that both the WPF and Silverlight solution want to build the same folder, e.g. Debug.  The work around for this to set the output path in the project properties:

outputfolder

Projects in separate folders using linked files

This is the way that I ended up choosing for almost every project in the solution.  It gives much more flexibility the previous option, because I can now have a clear separation between files that are just used for Silverlight and the WPF project.

So, how do you do this?  Well this time you create a new class library project in a new folder.  This leaves you with an empty project.  Now you have two projects, one for Silverlight and one for WPF, each in their own folder.

For any files that you need to share, you can use Visual Studio's Add Existing Item.  The difference is that instead of clicking Add, you click the drop down menu beside it and Add as Link:

addaslink

Normally, Visual Studio will copy the file to your project folder.  Using this feature it does not do this and simply references the file in the other folder.  This way any changes you make for the other project are automatically reflected in this one.

This opens up another problem, there are a number of features available only in WPF, or in Silverlight that you may wish to use.  With this linked file, if you use any of these features it may not compile in both projects.  The solution to this is to use the conditional compiling feature.  Any code that does not compile in Silverlight can be surrounded by these commands:

#if !SILVERLIGHT
[code goes here]
#endif

Of course it is the opposite situation where the code does not compile in WPF:

#if SILVERLIGHT
[code goes here]
#endif  

Unfortunately you'll find yourself using these far more than you would wish because there are so many differences between WPF and Silverlight.  I have resolved some of these issues by developing a WPF compatibility library to provide WPF functionality on Silverlight such as routed commands, routed events, FlowDocumentViewer, navigation etc.  We will be making it available as an open source library in the near future.

With this project setup or you can add files specific to Silverlight and WPF in their respective project folders as normal.

Sharing user controls

To share the code behind for your xaml files, create your user controls as normal in WPF.  e.g:

wpfctl

Then create the same control in Silverlight and delete the .cs file from the project.  Then you can add the existing CS file from the other project.  Unfortunately, when you are using linked files as code behind, Visual Studio doesn't display them as a child of the xaml file, even though it is correctly indicated in the project. So this is what you will end up with:

slctl

To share the xaml code between both projects you just have to copy and paste, unfortunately.

Sharing custom controls

Custom controls have a single xaml file themes/generic.xaml.  You need a separate file in both the WPF and Silverlight projects.  The code for each control can be linked to as described above.

 

So that is an overview of how we solved project management with Silverlight and WPF.  We hope that it is helpful and adequately explains how we have done this.

If you want to check out the WPF and Silverlight versions of the Virtual Tour Viewer, I'll be posting a new blog entry when I make them publicly available in the next week or so.

…Stefan

Tags:

WPF | Silverlight

Comments

11/28/2008 11:21:05 AM #

Trackback from Community Blogs

Silverlight Cream for November 28, 2008 -- #440

Community Blogs

12/2/2008 3:12:17 AM #

Pingback from mgalinks.wordpress.com

2008 December 02 - Links for today « My (almost) Daily Links

mgalinks.wordpress.com

1/16/2009 1:01:35 AM #

It's a very good article because If our projects are organized by layers (UI, Business, Data and others) this solution is reusing the business and Data layer without to modify any thing else except the UI layer.  In other words, we should to add a new partition simply for Silverlight and has a low cost of maintenance generally.

It's my personal opinion.

David Q.
Software Engineer
www.alomining.cl

David Quiroz

2/2/2009 9:17:59 PM #

Hi stefan
i need help.. im creating a silverlight application from the WPF and i am not doing the right way that you are describing up
can you help me plzz

roudi

4/14/2009 5:16:36 AM #

how can i have different xaml files for same .cs(user control)? this is to use visual state manager in xaml file for both WPF and silverlight as the namesapce are differnet in both for vsm.

Starter

4/23/2009 4:52:30 AM #

I shall try using this for converting it to silver light . lets hope for good .

Custom research paper

4/24/2009 9:48:49 PM #

I'm getting a problem, Visual Studio 2008 was crashing when trying to open XAML file? any thought on this issues? Thanks

tnomeralc web design toys

5/8/2009 2:35:43 AM #

However linking usercontrol (both xaml and cs) from SL project to WPF works !!! Smile At least control appears if added from code.

Tomasz Kubacki

6/29/2009 6:34:40 PM #

Yes only if Silverlight is a TRUE subset of .NET. I understand that SL 2.0 is beta and beta can have things that are not prime time. But when SL 2.0 goes live are we going to have controls in WPF that are not but are in SL 2.0?

SEO

7/13/2009 7:20:30 PM #

Pingback from answerspluto.com

list of urls - 5 « Answers Pluto

answerspluto.com

9/15/2009 5:32:43 AM #

How can i have different xaml files for same .cs(user control)? this is to use visual state manager in xaml file for both WPF and silverlight as the namesapce are differnet in both for vsm.

Emo

Emo

5/20/2010 10:57:31 AM #

Pingback from 440.mfbattle.com

Mizer Rescue, Mizer Visual Kei Stage Costumes The Gazette

440.mfbattle.com

Add comment




biuquote
  • Comment
  • Preview
Loading



About the author

Stefan Olson is the Managing Director of Olson Software.  He has been developing software using Microsoft Technologies for nearly 20 years.

He is currently working on building the next generation Virtual Tour software in WPF and Silverlight for www.palacevirtualtours.com.

Tag cloud