R – Creating a WPF front end for a Silverlight 3.0 application

silverlightwcf-ria-serviceswpf

I'm considering creating a WPF front end for a Silverlight application. Since Silverlight generally has the smaller subset of functionality this should be possible, but I'm not sure the best way to approach the problem. From the outset, let me say that I'm currently running the app out of browser but it lacks functionality like capturing system wide keypresses that I'd like to add, along with some W7 integration.

I've previously shared source between Silverlight and WPF by creating a project for each, then using "add as link" to link source files between the two. This time around I'll probably use .NET RIA Services to share source and business logic between the platforms.

The problem I see is sharing Xaml between the projects. It's pretty much copy and paste compatible, save for the namespaces, but that's not a great way to share the resources. Has anyone come up with a good way to share the Xaml between Silverlight and WPF?

A final option that crossed my mind was to have the WPF application use a Browser control to host the Silverlight app. Then I can add Windows specific features around that. To me this seems like the cleanest way to go from a development and testing perspective. What does everyone think?

Best Answer

Here is a trick you could use.

  1. Make sure your Silverlight Views and View Models are isolated within their own assembly that is easily referenceable by your WPF application.
  2. Add a reference to the Silverlight class library that houses the Views & View Models in the WPF application.
  3. Move the contents of the UserControl, "CustomerView" into a DataTemplate housed in a resource dictionary called "customerViewTemplate"

  4. Inside your root UI element XAML files in Silverlight and WPF do this:

<ContentControl ContentTemplate="{Staticresource customerViewTemplate}" />

  1. In the Silverlight application's App.xaml make sure to add the following Resource Dictionary reference to the merged dictionaries.

<ResourceDictionary Source="MyApp.Views;component/CustomerViewResources.xaml" />

  1. In the WPF application's App.xaml make sure to add the following resource dictionary reference to the merged dictionaries.

<ResourceDictionary Source="pack://application:,,,/MyApp.Views;component/CustomerViewResources.xaml" />

Sorry about the numbering, looks like Stack Overflow's ordered list mechanism is a little off.

The reason why this works is because you can't directly reference a Silverlight UserControl from XAML within WPF. It will give you the following error:

'Cannot resolve dependency to assembly 'System.Windows, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' because it has not been preloaded. When using the ReflectionOnly APIs, dependent assemblies must be pre-loaded or loaded on demand through the ReflectionOnlyAssemblyResolve event.

If you try to force the UserControl onto a WPF Grid using C# you will get the following 3 errors:

The best overloaded method match for 'System.Windows.Controls.UIElementCollection.Add(System.Windows.UIElement)' has some invalid arguments.

The type 'System.Windows.Controls.UserControl' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Windows, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'

cannot convert from 'ToWpfTest.Views.TestView' to 'System.Windows.UIElement'

I gather this is because the System.Windows.UIElement in WPF is not the same as the System.Windows.UIElement in Silverlight.

Related Topic