Adfa

Sharing code between WinForms/Web and Windows Phone

Published: 1/16/2013 9:00:03 PM

So recently I started developing for Windows Phone, just to try it out. One of my first apps was a port of a WinForms application that I had done before. One of the issues I faced during the development was the potential duplication of code since normal class libraries aren't compatible with Windows Phone projects. So what could I do to reuse some of the current code in my new project?

One obvious option is to simply copy the code to the Windows Phone project. While that most likely will work fine, it will result in duplicated code. From a maintainability point of view, duplicated code is not good and should be avoided. Another option is to add the source files to the Windows Phone project as links. This will not cause duplicated code, but the structure of the source code might get confusing due to the links. So are there any other options?

It turns out that there exist a project type named Portable Class Library in Visual Studio 2012 whose purpose is to enable cross-platform development. It can be used to create a class library that is usable in virtually all kinds of .NET projects, whether it is targeted for Windows Phone, XBox 360, Silverlight or .NET Framework. Although it is supposed to work with "every project", and therefore only contains a limited set of functionality, it is still very useful for basic logic.

For example, consider an application that calculates the volume of a sphere. A very simple application that might look something like this:

using System;
using System.Windows.Forms;

namespace Sphere
{
    public partial class SphereVolume : Form
    {
        public SphereVolume()
        {
            InitializeComponent();
        }

        private void calculateVolumeButton_Click(object sender, EventArgs e)
        {
            double radius;
            if(double.TryParse(radiusTextBox.Text, out radius))
            {
                double volume = CalculateVolume(radius);
                volumeTextBox.Text = volume.ToString();
            }
        }

        private double CalculateVolume(double radius)
        {
            return (4 * Math.PI * Math.Pow(radius, 3.0)) / 3;
        }
    }
}

Now we want to create a Windows Phone app for this application, but we don't want to duplicate the code that calculates the volume (yes, it's a silly example but you get the idea). That's when the portable class library gets useful.

First, add a new project of type Portable Class Library:

Next step is to select which frameworks you want to support. In this case, we want to support both .NET Framework and Windows Phone 8.

Now that the portable project is created we need to move the code to it. In this example I have created a helper class that contains the code:

using System;

namespace Sphere.Portable
{
    public static class SphereHelper
    {
        public static double CalculateVolume(double radius)
        {
            return (4 * Math.PI * Math.Pow(radius, 3.0)) / 3;
        }
    }
}

To fix the WinForms application we now need to add a reference to the Sphere.Portable project and modify the code accordingly:

using Sphere.Portable;
using System;
using System.Windows.Forms;

namespace Sphere
{
    public partial class SphereVolume : Form
    {
        public SphereVolume()
        {
            InitializeComponent();
        }

        private void calculateVolumeButton_Click(object sender, EventArgs e)
        {
            double radius;
            if(double.TryParse(radiusTextBox.Text, out radius))
            {
                double volume = SphereHelper.CalculateVolume(radius);
                volumeTextBox.Text = volume.ToString();
            }
        }
    }
}

Using this portable library in a Windows Phone project is just the same. First create a new Windows Phone App project that targets Windows Phone 8, then add a reference to the Sphere.Portable project. The source code might look something like this:

using Microsoft.Phone.Controls;
using Sphere.Portable;
using System.Windows;

namespace Sphere.Phone
{
    public partial class MainPage : PhoneApplicationPage
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private void calculateButton_Click(object sender, RoutedEventArgs e)
        {
            double radius;
            if(double.TryParse(radiusTextBox.Text, out radius))
            {
                double volume = SphereHelper.CalculateVolume(radius);
                volumeTextBox.Text = volume.ToString();
            }
        }
    }
}

And the Windows Phone app in action:

Even though the example was fairly simple I hope the point gets through. Using a portable library is a nice way to share core code between frameworks without having to duplicate code. Unfortunately for me, simply using a portable library wasn't enough in my original application since the core code contained a few framework-specific classes that couldn't be used in the library. Because of that I had to solve it in a slightly different way, but I will describe how in a later post.

Got comments? Post them here!

Name:

Name is optional but recommended.

E-mail:

E-mail is optional and will not be shown in the comment. It will only be used if the comment requires me to contact you directly.

Comment:
Enter text:


Popular tags
Security (5)
IIS (4)
Troubleshooting (3)
MVC (2)
TFS 2012 (2)