Question

Was wondering if someone had a good idea of how to handle this.

In WP7.1, we can utilize the excellent Windows Phone Toolkit to include some useful controls such as LongListSelector and Panorama. These are part of the Microsoft.Phone.Controls.Toolkit assembly.

In WP8, we do not need the toolkit for those two controls because they're part of the official Microsoft.Phone.Controls assembly.

I have multi-targeted my app so that I have two phone projects, WP71 and WP80, where I link files in WP80 to files in WP71.

This works great until I try to use the Panorama or LongListSelector control in a XAML page. In the WP80 project, if I reference the WP80 DLL of the phone toolkit, it does not include the two aforementioned controls because, surprise, they're already present.

The issue is, WP71 needs the namespace declaration at the top of the XAML and the namespace is different for both projects.

WP71:

xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"

<toolkit:Panorama />

WP80:

xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"

<phone:Panorama />

I cannot build the projects because each project thinks the namespace is incorrect if I just use one because they need to point to different assemblies.

I don't think I can use compile constants in my XAML, otherwise that would be a fix.

My workaround was originally to just reference the older WP71 DLL in my WP80 project. But other 3rd party libraries bind against the official 8.0 SDK DLL (Caliburn, in my case) so it causes problems.

How can I solve this pickle? The only idea off the top of my head was to resort to code-behind to create the instance of the control :( Is there a better way?

Was it helpful?

Solution

Don't use a link, create a separate view for each.

Another solution might be to create a PanoramaEx control in each of the relative projects and inherit from Panorama. Then the view would reference the PanoramaEx control and you could still use a link to a single view. That's if both UI projects have the same namespace.

Edit: isn't panorama for WP7 in the namespace:

 xmlns:controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"

I do use my initial solution for ProgressBar and PerformanceProgressBar, I have a ProgressBarEx in each UI project, the WP7 one inherits from ProgressBar and the WP8 one inherits from PerformanceProgressBar and then in the views I reference ProgressBarEx.

OTHER TIPS

Might not be the most elegant solution, but you can try to use a T4 file (.tt file) to generate both targets.

<#@ template language="C#" hostspecific="true"#>
<#@ output extension=".xaml"#>
<#@ assembly name="EnvDTE" #>
<phone:PhoneApplicationPage
    x:Class="PhoneAppDemo.Pages.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
<# IServiceProvider serviceProvider = (IServiceProvider)Host;
   EnvDTE.DTE dte = (EnvDTE.DTE)serviceProvider.GetService(typeof(EnvDTE.DTE));
   var configName = dte.Solution.SolutionBuild.ActiveConfiguration.Name;
   if (configName == "WP7") { #>
    xmlns:controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"
<# }else{ #>
    xmlns:controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
<# } #>
    >
<# include file="Page.xaml" #>
</phone:PhoneApplicationPage>

In this example, the inner content of the Page is in "Page.xaml". We just encapsulate it in <phone:PhoneApplicationPage> at processor time, based on the target name (usually Debug and Release, but in this example we assumed there was a target WP7).

For other stuff related to a multi-targeted silverlight app, you can always read Maintaining a WP7 and WP8 version of a same Silverlight application.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top