Click here to monitor SSC
Av rating:
Total votes: 29
Total comments: 11


Khawar Yunus
One application in both WPF and Silverlight
05 October 2010

Because Silverlight is a development of Windows Presentation Foundation, and the technologies are so interlinked, it would seem obvious that there would besuch  a high degree of code compatibility that one could then develop an application for both platforms from a common code-base. Khawar describes how it can be done, and shows the results.

There seems to be lots of interest in porting Windows Presentation Foundation (WPF) and WinForms application to Silverlight, and occasionally from Silverlight applications to WPF as well.  Because of this, I wanted to see how feasible it was to maintain the bulk of my code in a single code-base, and provide just the code- glue to support the framework.  I happened to have a cool looking erlight application, so I decided to convert this to WPF in the hope that it would give me an insight to the tasks of porting between the two frameworks. It did.

I had to come to terms with the reality that one cannot hope or expect to share 100% of the code base by merely inserting conditional compilation preprocessor directives in any application more complex than the’ Hello World’ application. 

First Magic Ingredient: Preprocessor Directives

Preprocessor directives are the basic way of  maintaining  a single code base, whilst porting to WPF , WinForms and Silverlight.  Preprocessor directives are basically just conditional statements within your code.  They are different from the regular conditional statements in a sense that  they don't execute at run time.  They are interpreted by the compiler before it performs the compilation passes.  If a block of code is in a conditional statement that returns true, then that block will get compiled: If it returns false, then that block of code doesn't get compiled.  For example, In the following code I am telling the compiler that if the code file that is being compiled is in a Silverlight project then compile this section of the code otherwise compile the other section of the code that would be used with regular .net applications such as WinForms, or WPF.

#if SILVERLIGHT

       IPopupWindow popWindow = new ChildWindowEx();

#else

       IpopupWindow popWindow = new WPFPopupWindowEx();

#endif 

Visual Studio is very smart when it comes to conditional preprocessor directives.  It will automatically gray out the inapplicable code block based on the condition.  For example, if this code was part of the Silverlight project then the else block will automatically be grayed out.

Second Magic Ingredient: Linking to a file

The second Magic Ingredient is linking files within projects.  We are all used to right clicking the project file -> Add -> New Item... to add a new item of course: But if you look right below that, there is another option that says "Existing Item...".  Now you can click that and select a file from your WPF project to share in the  Silverlight port of that project.  However, that isn’t really what we want, because it creates a copy of that file into the Silverlight project.  But if you click the drop arrow of that Add split button on the "Add Existing Item" dialog, instead of clicking the add button, then you will reveal another option of "Add as a Link": That is the one you want to click.  That will just create a short cut of that file in your current project.  If you combine this technique with preprocessor directives you can then share code between two different projects targeted for two different platforms. 

Maintaining the balance:

When you are aiming to achieve a single code base, you shouldn’t compromise your code readability. You will always come across a code file where no common code would be possible.  This code would become unreadable if you just used conditional compilation.  If we are using single code base to make applications more maintainable then this would defeat the purpose. We’re aiming to decrease the time to update or make changes to applications, and to reduce bugs by sharing the same logic. If the code isn't readable then, for sure, it will not be easy to maintain. On the contrary, it will take more time to make changes. 

So in the case where a file has a considerable difference between platforms there are two possible solutions.

  • You could split the file into two.  One half will contain the code (logic) common to both, which will be easily shared between the two platforms, and the other half will have a version for each platform.
  • You could subclass the original file and create two separate versions of the derived class one for each platform.

Which approach you use depends on which method provides the best maintainability and portability of the code, both now and in the future.  I have used both techniques.

Other Challenges

Even though one won't be able to share 100% of the code base, we can on average share good 70% if the application is well architected.  

There are ways of increasing the proportion of common code by careful planning. You will, for example, notice if you are going to Silverlight to WPF that there is no ChildWindow or BusyIndicator classes.  Both of these classes are very common in Silverlight application.  One alternative is to use Window class, spawn a new window, in WPF to replace both of those. This is the natural solution in the Windows environment.  However, if you need exactly the same behavior as in Silverlight for ChildWindow and BusyIndicator classes, then it's actually not that difficult to create those control from scratch in WPF. And if you port between Silverlight and WPF regularly, than it might be good idea to create those controls as they would come handy for future projects.  For my demonstration I need exactly this ChildWindow and BusyIndicator functionality in Silverlight for my WPF conversion, so I ended up creating those controls.

Although you can achieve a lot by bringing the two versions to a common denominator, you may lose functionality if you take this too far. As an example of this, my Silverlight application uses some beautiful transitions between screens.  Those are custom transition made possible via the projection plane properties in Silverlight. As you know, there is no projection plane in WPF.  They have something more powerful, which is ViewPort3D.  So in such cases where the other framework offer better and more powerful options then I think one should not be afraid to deviate a little and take advantage of those.  In other words, it's better to not have the conversion so exact that the applications are 100% identical if one can exploit the unique features of the platform to make the converted application better than the original.  In this case I believe that the 3D transitions that I used in converted WPF application are better than the transitions in the Silverlight application.

Here is the browser-based silverlight version of the application. To view it, you'll need to have Silverlight installed in your browser.

Here is a video of the WPF application.


submit to reddit

This article has been viewed 11635 times.
Khawar Yunus

Author profile: Khawar Yunus

Khawar Yunus (MCTS - WPF) - Sr. Programmer / Architect, brings 12+ years of industry experience in developing, architecting online, desktop and client/server software using Microsoft technologies. He is Microsoft Certified Technology Specialist in WPF application development. He has provided consulting services to some of the most recognized companies including Mary Kay, Wells Fargo and Hill Holliday. He specializes in WPF, Silverlight and ASP.net application development using .net and SQL Server.

Search for other articles by Khawar Yunus

Rate this article:   Avg rating: from a total of 29 votes.


Poor

OK

Good

Great

Must read
 
Have Your Say
Do you have an opinion on this article? Then add your comment below:
You must be logged in to post to this forum

Click here to log in.


Subject: advice on structuring your solution and project files
Posted by: Dale Barnard (not signed in)
Posted on: Thursday, October 07, 2010 at 11:26 AM
Message: If you attempt this cross-platform development, I can suggest a way to structure your solution files and projects. It's basically a separate solution for each platform (Silverlight, WPF, or Windows Phone 7) with each linking to the same source files. I have been doing this for quite some time now, and it seems like a very solid way of handling the complexity. I blogged about it here: http://dalebarnardonwpf.wordpress.com/2010/03/31/compiling-an-application-in-silverlight-or-wpf/

Subject: Code
Posted by: Anonymous (not signed in)
Posted on: Friday, October 08, 2010 at 2:15 AM
Message: Well written article! I would be useful if you could provide the code for a sample project.

Subject: missing code/sample
Posted by: Anonymous (not signed in)
Posted on: Friday, October 08, 2010 at 2:45 AM
Message: where is the sourcecode/democode?..

Subject: What about XAML?
Posted by: Anonymous (not signed in)
Posted on: Sunday, October 10, 2010 at 2:49 PM
Message: And what about XAML?
Can compiler directives be used there?
How to manage the differences? Just by using separate XAML files fro each platform?

Subject: In response to: What about XAML?
Posted by: Khawar Yunus (Author) (not signed in)
Posted on: Sunday, October 10, 2010 at 9:54 PM
Message: What about XAML?
Yes that's were the problem lies. compiler directives can't be used in XAML files. Hence i mentioned in the article that even if we can't share 100% of the code base, we can on average share good 70% if the application is well architected. Until we get conditional compilation in XAML the strategy to achieve increase percentage of shared code base is to re-factor your xaml files such that your xaml files contains users controls that are compatible with both Silverlight and WPF platforms. This way one can limit the number of xaml that is platform specific. Hope this answers your question.

Subject: Thank You
Posted by: Ove (view profile)
Posted on: Monday, October 11, 2010 at 12:03 AM
Message: Thank You for an interesting article!
I would really appreciate if You could provide the code for a sample project.

Subject: Good but no sample code
Posted by: Anonymous (not signed in)
Posted on: Monday, October 11, 2010 at 1:25 AM
Message: Very good subject but is will be more useful if there was a sample project to download.

Any chance if a download link can be made available?

Subject: Regarding Code Request
Posted by: Khawar Yunus (Author) (not signed in)
Posted on: Monday, October 11, 2010 at 10:30 AM
Message: I apologize, but this project is not a small sample project. This project comprises of many components that are intellectual property of my company. Therefore, we cannot share the code. I hope this is ok.
Thank you.

Subject: I a free with the idea
Posted by: pauler (view profile)
Posted on: Monday, November 01, 2010 at 4:02 AM
Message: I would just add
Wrap all, yes all
Compiller directives code in one class or name space that has no core logic.
Then call that form your main code base.

In the long run this is the way to go.

Subject: I am skilled
Posted by: pauler (view profile)
Posted on: Monday, November 01, 2010 at 4:07 AM
Message: I'm a skilled research in .NET
I can Remold .NET apps live in mem(non debug)
I can walk a live object structure
I can get the value/code for most any object live

I think it would be fun to work for Red Gate
I'm not in the UK, so can't get in with HR at Red Gate.


Subject: Should mention MVVM
Posted by: sdmcnitt (view profile)
Posted on: Monday, November 01, 2010 at 5:18 PM
Message: an article with this topic should at least mention some of the techniques in MVVM. I recommend that the readers check out this pattern -- especially if you are starting from scratch.

 






recommended site pinvoke

PInvoke.net is a user-driven wiki which provides .NET developers with native method signatures, so they don't have to spend time writing them from scratch.




Top rated articles
C# Async: What is it, and how does it work?
 The biggest new feature in C#5 is Async, and its associated Await (contextual) keyword. Anybody who is... Read more...

Towards the Perfect Build
 An automated build and deployment system is no longer a dream. Now that PowerShell has matured as a... Read more...

Practical PowerShell: Pruning File Trees and Extending Cmdlets
 One of the most radical features of PowerShell is amongst the least known. It is possible to extend... Read more...

TortoiseSVN and Subversion Cookbook Part 4: Sharing Common Code
 Michael Sorens continues his series on source control with Subversion and TortoiseSVN by describing... Read more...

Feature Usage Reporting in Early Access Programs
 After doing Web development, you can get very used to the luxury of having basic information about your... Read more...

Most viewed articles
A Complete URL Rewriting Solution for ASP.NET 2.0
 Ever wondered whether it's possible to create neater URLS, free of bulky Query String parameters?... Read more...

Visual Studio Setup - projects and custom actions
 This article describes the kinds of custom actions that can be used in your Visual Studio setup project. Read more...

.NET Application Architecture: the Data Access Layer
 Find out how to design a robust data access layer for your .NET applications. Read more...

Web Parts in ASP.NET 2.0
 Most Web Parts implementations allow users to create a single portal page where they can personalize... Read more...

Calling Cross Domain Web Services in AJAX
 The latest craze for mashups involves making cross-domain calls to Web Services from APIs made publicly... Read more...

Over 400,000 Microsoft professionals subscribe to the Simple-Talk technical journal. Join today, it's fast, simple, free and secure.

Join Simple Talk