The new thing for VS 2013 is Universal Apps. They allow you to create a Win 8 and Phone app with shared code. But what if you’re writing LOB apps in WPF, maybe using MVVM? You may have a Winforms app and a XAML app, and want to share code; or have two WPF apps that share a core code base, and some screens.
This post walks through creating a sample shared app.
Create WPF App
I’ll just cover WPF in this post. Start by creating a new application:
Okay, so we have a WPF application (as you might already have). How to create a shared project? Well, the bad news is: you can’t; at least as far as I’m aware (please, please, please let me know in the comments if you know this to be false!).
So, if you can’t create a shared application without a universal one then create a universal one in the same solution:
This creates a shared app with a reference from Windows 8.1 and Windows Phone 8.1:
Now, what comes next might feel like a hack… and there’s a good reason for that!
Have a look in the Win 8 app csproj:
Copy this into the csproj file of the WPF project (remember the path may be different - although in this case, are not):
The important thing here is the `Label`. However, you’re most likely to get the path wrong. If you do then when you update the project in VS it will fail to load and give you an error message telling you where it’s trying to find the shared project. Having done this a couple of times, my advice is have this error message up, and try to navigate to the path in Windows Explorer: you should see where you went wrong quickly enough.
Adding stuff to the shared project
Start by adding a page to the shared project so that we can see that it works:
Make it obvious so that you can recognise it:
Okay, so you’ve now created a shared project, added some shared content, and referenced it from your main project. Next, tidy up by removing Windows 8 and Phone 8 apps and add a second WPF app:
To make sure that this is, in fact, a shared project, create and make the same change to the second project and then modify each to call the shared page; e.g.:
private void Button\_Click(object sender, RoutedEventArgs e)
{
TestPage test = new TestPage();
Window w = new Window();
w.Content = test;
w.Show();
}
Then run both projects:
Notes, and using this in an MVVM architecture
Okay - some things that are worth noting here. The main thing is this: the shared code is just that - shared. If you call something like:
typeof(TestPage).Assembly
You will get the assembly of the running application. Effectively, you’ve created a kind of link between the projects, without the messiness of actually creating a link. The consequences of this are that you must ensure that code in the shared project only has dependencies that can be resolved in ALL the projects that include the shared project.
MVVMCross
I’ve tried this on MVVM Cross using two projects and sharing XAML files; and it works. MVVM Cross looks in the current assembly for a `MyView`, when you navigate to a `MyViewModel`. It will find it providing all your projects reference the shared project and you do not try to re-implement the view.
To clarify:
-
Creating a shared project between Winforms and WPF that shares a XAML file will most probably not work (admittedly I haven’t tried it).
-
Creating a shared project for two WPF projects and copying MyView.xaml into the shared project, leaving the original intact will cause MVVM Cross to fail to resolve the page (because it doesn’t know which one you want).