Showing posts with label pivot. Show all posts
Showing posts with label pivot. Show all posts

Wednesday, 15 May 2013

Why setting a control Height and Width to 0 is not the brightest idea inside a Windows Phone project

I am doing this small post because I have battled the whole morning with this bug and finally got it and it might save you some time if you read it and have the same problem. 

Scenario: Pivot with two items and at some point the swipe on one of the items doesn't work anymore. Putting a button on the PivotItem that doesn't swipe I can still change the selected item and the second item still swipes correctly.

Cause: I was setting the Height=0 and Width=0 on a control inside the PivotItem (in my project I don't want my control to be collapsed). The problem presents itself if you set any of the controls inside a PivotItem to Height and Width = 0 when the PivotItem is selected. If on the other hand you set the Height and the Width to anything >1 the PivotItem continues to swipe correctly. Even more strange: if the PivotItem is not selected when  you set the Width and Height to 0 and swipe to the control's PivotItem everything will still work correctly. So pay attention better not use set Width and Height =0 on UI controls. 

If you want to test it yourself and maybe tell me what really happens I am attaching a small project created from a Windows Phone Pivot application where I've added a menu that will set the Height and Width of the list inside the first PivotItem to 0. I also set the background of the first PivotItem to green so you will see that it is still expanded. 



How to reproduce the problem: If you execute the menu command with the first PivotItem selected you will see that the pivot doesn't swipe anymore. If you change the values to 1, run the app again and execute the menu with the first PivotItem selected you will see that the pivot still swipes correctly. If, on the other hand, you let the values set to 0 but when executing the menu you have the second PivotItem selected you will see that the first item stil swipes correctly. Bug? Feature? Just pay attention to setting controls to Width and Height 0 because you might have problems with the UI and you won't know what is causing it.


NAMASTE









Thursday, 9 May 2013

Type forwarding and XAML sharing between WP OS 7.1 and 8.0 projects

    This post is about a new feature available in Windows Phone OS 8.0 SDK called Type Forwarding.

    Have you ever wondered how does the Windows Phone 8.0 SDK handles the fact that the Panorama, Pivot controls changed the namespace and the assembly from OS 7.1 SDK to OS 8.0 SDK? (80% that you haven't :) ). I recently had to migrate an OS 7.1 project to OS 8.0, but also keep the old one (duplicated the old project and upgrade the duplicated one).

    Here is the story of what happens when you upgrade an OS 7.1 project that uses Panaroma or Pivot to OS 8.0:
    If you start a new Windows Phone Pivot App with the target OS 8.0 inside MainPage.xaml the prefix "phone" is used for the Pivot control where "phone" is:

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

    If, on the other hand, you create a new Windows Phone Pivot App with the target OS 7.1 inside MainPage.xaml the prefix "controls" is used for the Pivot/Panorama control where "controls" is:

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

    The real "magic" happens when you upgrade the Windows Phone 7.1 project to OS 8.0. The MainPage.xaml page doesn't change (you will still see the "controls" tag is kept in order to be able to better share the code between the versions), but instead a reference to Microsoft.Phone.Controls.dll is added to the OS 8.0 reference that is not used if you create a new project with target OS 8.0. If you wonder if by adding this reference you use the old version of the controls the answer is NO. What this assembly does is that is uses a really neat and new  feature of the .Net compiler called Type Forwarding. This feature can be used when you move a class from one namespace/dll (assembly) to another and you don't want to recompile the application to reference the new dll but you will only deploy the two dlls where the first one (the one that the application already knew uses the Type Forwarding to tell the application that a certain class/es moved to another assembly). In the case of Windows Phone OS 8.0 SDK the usage is even "cooler" as it enables you to use the same XAML for both OS 7.1 projects and OS 8.0 ones. Inside AssemblyInfo.cs of Microsoft.Phone.Controls.dll OS 8.0 version we have all the declarations needed to forward the types to their new locations:

 [assembly: TypeForwardedTo(typeof(Panorama))]  
[assembly: TypeForwardedTo(typeof(PanoramaItem))]
[assembly: TypeForwardedTo(typeof(Pivot))]
[assembly: TypeForwardedTo(typeof(PivotItem))]
[assembly: TypeForwardedTo(typeof(PivotItemEventArgs))]
[assembly: TypeForwardedTo(typeof(AnimationDirection))]
[assembly: TypeForwardedTo(typeof(PanningBackgroundLayer))]
[assembly: TypeForwardedTo(typeof(PanningLayer))]
[assembly: TypeForwardedTo(typeof(PanningTitleLayer))]
[assembly: TypeForwardedTo(typeof(PanoramaPanel))]
[assembly: TypeForwardedTo(typeof(PivotHeaderItem))]
[assembly: TypeForwardedTo(typeof(PivotHeadersControl))]

I am attaching a small project called TypeForwarding that implements the same functionality as Microsoft.Phone.Controls.dll OS 8.0 version.

Other usages that I can thing of:

  • Flurry SDK changes the name of the namespace for the Api class for WP7SDK to WP8SDK (bad choice when you need code sharing). If you want to keep the same code for the OS 7.1 and the OS 8.0 version of the app you will have to use conditional compiling for every file where you use the Api class. Much easier would be to create an OS 8.0 library project with the default namespace WP7SDK and forward the Api class to the WP8SDK added as a reference to the library project. This way the old WP7SDK will continue to work as it was on the OS 8.0 using the OS 8.0 version of the Flurry SDK.
  • MVVM Light. If you use inside your XAML the EventToCommand this is not xaml shareable between OS 7.1 and OS 8.0 because the assemblies changes from GalaSoft.MvvmLight.Extras.WP71.dll to GalaSoft.MvvmLight.Extras.WP8.dll. The easiest approach in this case (an open source) would be to recompile the dll and use the same name for both versions of the dll. But if you don't have access to the source code of the dll you could use type forwarding.  Also a third approach would be to derive your on class like MyEventToCommand and use this inside the xaml.
Keep in mind this neat feature because you might need it. I would also love to see, in the next version of the SDK, the possibility to use MarkupExtension this way we could conditionally compile parts of the XAML depending on the version of the SDK the app is running on. Have a look at this blog post that explains how it works on WPF projects.



Till next post NAMASTE and have fun coding for Windows Phone!