Tag: Visual Studio 2010

Splash Screens

If you start developing a new Windows Phone 7 application, you usually start by creating a new Visual Studio 2010 project. As part of the initial project, Visual Studio creates a default splash screen for you, consisting of a waiting clock.

DefaultSplashScreen

A Windows Phone splash screen is simply a jpg file with a resolution of 800 * 480 pixels. This means that it is very simple to replace the default splash screen (which is conveniently stored in your Visual Studio project under the name SplashScreenImage.jpg). Just make sure you have a jpg file with the right resolution and also make sure that it is placed in the root of your Visual Studio project. The name must be SplashScreenImage.jpg and its Build Action must be set to Content in the Properties window. Leaving the original splash screen unchanged in your own application gives end users a somewhat boring experience. After all, a splash screen is used to give users the impression that your application starts fast, and it also occupies users while your application is loading. If all applications use the same default splash screen, it will not help giving users a fast starting impression about those applications. So it is important to provide your own splash screen. If an application does not spent much time initializing, the actual amount of time that a splash screen is displayed is very short. For one of my applications, I did create a reasonably nice splash screen, to find out that the splash screen often is displayed for less then a second. My initial thought was to delay application start to allow end users to admire my splash screen. Of course this is a very bad idea, something you should not even consider doing.

SplashScreen1

This splash screen is used in a little game that is available on Marketplace. Typically the game starts up in under a second, meaning the user hardly has time to see the splash screen. The good news is that it is at least not the default splash screen. I have to admit that I considered adding a delay in my application for users to see the splash screen. Of course, and end user might like it once to take a look at this splash screen, but after starting an application several times, the splash screen will become boring since it is just a static image.

On a side note, if you are curious about this game, you can find it here on the Windows Phone 7 Marketplace. Note: This link will work from a Windows Phone 7, or from a PC with Zune software installed.

Back to the story about splash screens though. If you are developing a Silverlight application for Windows Phone 7, take the following idea into consideration.  By far the best experience you can give end users for fast starting applications, is to take a screen shot from your application’s main page. If your application starts with some animation, make sure to take the screen shot from the initial situation (before the animation starts running).

SplashScreen2

Capture

Also, leave the application title / page title out of the splash screen. What I did for my latest application was taking the following shot from the main screen. Once the application is initialized, the application and page title animate in from the top, nice and gently. This gives a very nice experience for end users, and you don’t have to worry that your splash screen is only visible for a very short time, after all, your splash screen partly is your main page.

 

To have some nice page transitions on your main page, you can make use of functionality that is available in the November release of the Silverlight for Windows Phone Toolkit. An in-depth explanation of how to use these page transitions can be found in this MSDN  blog entry by Will Faught.

This is the code that I am using to bring in the application title and page title in an override version of the OnNavigatedTo method:

  1. protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
  2. {
  3.     base.OnNavigatedTo(e);
  4.  
  5.     if (Settings.Instance.ApplicationLaunching)
  6.     {
  7.         SlideTransition slideTransitionFadeIn = new SlideTransition { Mode = SlideTransitionMode.SlideDownFadeIn };
  8.         ITransition transitionTitle = slideTransitionFadeIn.GetTransition(this.TitlePanel);
  9.         transitionTitle.Completed += delegate { transitionTitle.Stop(); };
  10.         transitionTitle.Begin();
  11.         Settings.Instance.ApplicationLaunching = false;
  12.     }
  13. }

Only when my application is launching (a new instance of the application is started, or the application returns from being tombstoned), the animation will run. In all other situations ‘normal’ page transitions will be executed. I keep track of the application being launched in the app.xaml.cs source file like this:

  1. // Code to execute when the application is launching (eg, from Start)
  2. // This code will not execute when the application is reactivated
  3. private void Application_Launching(object sender, LaunchingEventArgs e)
  4. {
  5.     Settings.Instance.IsTrialMode = RunningMode.CheckIsTrial();
  6.     Settings.Instance.ApplicationLaunching = true;
  7. }
  8.  
  9. // Code to execute when the application is activated (brought to foreground)
  10. // This code will not execute when the application is first launched
  11. private void Application_Activated(object sender, ActivatedEventArgs e)
  12. {
  13.     Settings.Instance.IsTrialMode = RunningMode.CheckIsTrial();
  14.     Settings.Instance.ApplicationLaunching = true;
  15. }

As you can see, a little bit of code and an additional screen capture from of your application gives you a simple splash screen that is effective for fast loading applications, yet giving the end users a very nice starting experience of your application.

Configuration dependent references

When you are developing Windows Phone 7 applications, especially if you are using additional assemblies that you developed yourself, it might not be sufficient to just add a reference to those particular assemblies from inside Visual Studio 2010. For instance, take this scenario that is taken from a real Windows Phone application:

AddingReferences(1)

This application makes use of an assembly that contains lots of re-usable functionality around MVVM support, IsolatedStorage support for tombstoning purposes and a few goodies to test an application’s Trial mode support. The latter item is the one I want to talk about in more detail in this article.

On a side note: even though I partly re-invented the wheel, there is a very nice MVVM implementation available with great Windows Phone 7 support. Take a look at Galasoft’s MVVM Light, a great resource for developing ‘serious’ Windows Phone 7 applications.

If you are developing Windows Phone 7 applications, you are most likely aware of the fact that the IsTrial method of the LicenseInformation class always returns false when running your application locally from a development machine. In order to test your application’s behavior in trial mode, you probably end up with something like this:

  1. using Microsoft.Phone.Marketplace;
  2.  
  3. namespace DotNETForDevices.Tools.Controls
  4. {
  5.     public class RunningMode
  6.     {
  7.         public static bool CheckIsTrial()
  8.         {
  9. #if DEBUG_TRIAL
  10.             return true;
  11. #else
  12.             return new LicenseInformation().IsTrial();
  13. #endif
  14.         }
  15.     }
  16. }

By defining a conditional compilation symbol ‘DEBUG_TRIAL’, it is now possible to test the application as if it is running in trial mode. However, if you are lazy like me, you probably get tired of manually setting conditional compilation symbols. I am also afraid to forget undefining symbols like this one when I submit applications for verification, especially since the above code snippet lives in a separate  assembly. For me, it would be very helpful if I could create an additional configuration, that would allow me to build my entire solution for trial mode testing. Creating a new build configuration is very easy inside Visual Studio.

CreatingNewConfiguration

Inside this new configuration I can define my DEBUG_TRIAL conditional compilation symbol as well as additional symbols. Because I derived my new configuration from the existing Debug configuration, all other settings in my new configuration are copied from the existing Debug configuration. This is exactly what I want. Unfortunately though, even though I can define additional settings, at first sight it seems that Visual Studio 2010 does not help me to refer to other versions of assemblies that I add to my solution. In other words, I would really like to refer to a DebugTrial build of my additional DotNETForDevices.Tools.Controls assembly when I am building my application in the DebugTrial configuration. Of course I want Visual Studio to update to the Release configuration of all my own assemblies as well when I decide to build my solution in Release mode. If you take a look at the path to my referred assembly when I switch from Debug mode to DebugTrial or to Release mode, you will see that the referred assembly is still the original Debug assembly.

AddingReferences(2)

At first glance it seems that there is no way to be able to import my own assemblies with the same build configuration that I am using during the current build of my solution. There is a way to overcome this situation. As you might now, Visual Studio 2010 project files are XML based files, so it is possible to view them with a text editor and it is even possible to modify them. Of course you have to be very careful with modifying project files because it might lead to Visual Studio not being able to open your project any longer. If you want to modify your project files, make sure to always make a back-up of the original file.

  1. <ItemGroup>
  2.   <Reference Include="DotNETForDevices.Tools.Controls">
  3.     <HintPath>..\..\..\DotNETForDevices\Controls\Bin\Debug\DotNETForDevices.Tools.Controls.dll</HintPath>
  4.   </Reference>
  5.   <Reference Include="DotNETForDevices.Tools.Persistence">
  6.     <HintPath>..\..\..\DotNETForDevices\Persistence\Bin\Debug\DotNETForDevices.Tools.Persistence.dll</HintPath>
  7.   </Reference>
  8.   <Reference Include="Microsoft.Phone" />
  9.   <Reference Include="Microsoft.Phone.Interop" />
  10.   <Reference Include="System.Windows" />
  11.   <Reference Include="system" />
  12.   <Reference Include="System.Core" />
  13.   <Reference Include="System.Net" />
  14.   <Reference Include="System.Xml" />
  15. </ItemGroup>

Looking inside my Clicker.csproj file, it becomes clear that the paths to referred assemblies are defined in a configuration independent way. This is fine for all system assemblies, but less ideal for my own assemblies, especially since they might still be under development as well. If you take a further look inside the *.csproj file, you will see that there are configuration dependent definitions.

  1. <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
  2.   <DebugSymbols>true</DebugSymbols>
  3.   <DebugType>full</DebugType>
  4.   <Optimize>false</Optimize>
  5.   <OutputPath>Bin\Debug</OutputPath>
  6.   <DefineConstants>DEBUG;TRACE;SILVERLIGHT;WINDOWS_PHONE</DefineConstants>
  7.   <NoStdLib>true</NoStdLib>
  8.   <NoConfig>true</NoConfig>
  9.   <ErrorReport>prompt</ErrorReport>
  10.   <WarningLevel>4</WarningLevel>
  11. </PropertyGroup>
  12. <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
  13.   <DebugType>pdbonly</DebugType>
  14.   <Optimize>true</Optimize>
  15.   <OutputPath>Bin\Release</OutputPath>
  16.   <DefineConstants>TRACE;SILVERLIGHT;WINDOWS_PHONE</DefineConstants>
  17.   <NoStdLib>true</NoStdLib>
  18.   <NoConfig>true</NoConfig>
  19.   <ErrorReport>prompt</ErrorReport>
  20.   <WarningLevel>4</WarningLevel>
  21. </PropertyGroup>

It seems that conditions can be defined very easy inside project files. If I could do something similar for paths to assemblies that I have added as references, I could add assemblies with the same build configuration as my current solution has. This guarantees me building against the right configuration of my own additional assemblies. So this is the final solution I came up with, indeed modifying the project file manually:

  1. <ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
  2.   <Reference Include="DotNETForDevices.Tools.Persistence">
  3.     <HintPath>..\..\DotNETForDevices\Persistence\Bin\Debug\DotNETForDevices.Tools.Persistence.dll</HintPath>
  4.   </Reference>
  5.   <Reference Include="DotNETForDevices.Tools.Controls">
  6.     <HintPath>..\..\..\DotNETForDevices\Controls\Bin\Debug\DotNETForDevices.Tools.Controls.dll</HintPath>
  7.   </Reference>
  8. </ItemGroup>
  9. <ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
  10.   <Reference Include="DotNETForDevices.Tools.Controls">
  11.     <HintPath>..\..\DotNETForDevices\Controls\Bin\Release\DotNETForDevices.Tools.Controls.dll</HintPath>
  12.   </Reference>
  13.   <Reference Include="DotNETForDevices.Tools.Persistence">
  14.     <HintPath>..\..\DotNETForDevices\Persistence\Bin\Release\DotNETForDevices.Tools.Persistence.dll</HintPath>
  15.   </Reference>
  16. </ItemGroup>
  17. <ItemGroup Condition="'$(Configuration)|$(Platform)' == 'DebugTrial|AnyCPU'">
  18.   <Reference Include="DotNETForDevices.Tools.Controls">
  19.     <HintPath>..\..\DotNETForDevices\Controls\Bin\DebugTrial\DotNETForDevices.Tools.Controls.dll</HintPath>
  20.   </Reference>
  21.   <Reference Include="DotNETForDevices.Tools.Persistence">
  22.     <HintPath>..\..\DotNETForDevices\Persistence\Bin\DebugTrial\DotNETForDevices.Tools.Persistence.dll</HintPath>
  23.   </Reference>
  24. </ItemGroup>

Changing to another build configuration now also results in referring to assemblies that correspond with that particular build configuration.

AddingReferences(3)

One very important thing to keep in mind though is that you need to manually modify the project file each time you add references to additional assemblies that you own and that you want to be build configuration aware. Other than that, I have not seen any issues by extending project files for this particular purpose. However, things might of course change with future versions of Visual Studio.

Publishing my first Windows Phone 7 application

MobileAppTileSmallOver the last year I have spent a lot of time talking about Windows Phone 7 development, both at (international) conferences, for students and at companies. During these presentations I always used a significant part of my speaking time to show Visual Studio 2010 in action. Live coding is something I like to do, and definitely helps showing an audience how powerful the development tools for Windows Phone 7 application development are. One question I got frequently was to show the applications I already had published on the Windows Phone 7 Marketplace. Up until now I have not really been interested in publishing Windows Phone 7 applications, teaching folks how to develop these applications is just more fun for me. However, over the last couple of weeks I decided to create a simple application for publication on Marketplace. Even though simple, the application is making use of MVVM instead of making use of code behind files. Making use of MVVM helped testing the application and definitely increases maintainability. To my surprise, getting the application certified and published was a very simple process. It was just a matter of submitting my (obfuscated) XAP file, some artwork, screen shots and a description. A few more details needed to be filled out on the submission pages, like a category under which the application will be visible on Marketplace, the price for the application and support for Trial mode. All in all, submitting the application took less then 15 minutes. After some waiting time (which can vary between a couple of hours and a few working days), I got an email, indicating successful submission to Marketplace. This process is easy and fast. Funny enough, it also made me feel good to see my own application available on Marketplace. I really start getting excited about submitting Windows Phone 7 applications. Just wait and see. I am pretty sure I will get more applications out to Marketplace. Oh, just in case you are curious: You can find my first ever published Windows Phone 7 application by clicking on this link to Marketplace. Note: This link will work from a Windows Phone 7, or from a PC with Zune software installed.

A small design-time issue with Visual Studio 2010

During the development of my first Windows Phone 7 application that will appear soon on the MarketPlace, I ran into a small issue with Visual Studio 2010. For the game I am developing I am making use of a number of UserControl’s. They contain a lot of intelligence about how to be drawn, what action to be taken and a few more things. I am also making use of a number of application settings, wrapped inside a class and stored in IsolatedStorage. These settings can be modified using a Settings Screen, and after modification, the settings will immediately be stored to IsolatedStorage without user intervention. So far so good. Until I decided to make use of a number of these settings inside my UserControl. All of a sudden I got exceptions in the designer.

DesignerException

Interestingly enough, the exceptions occur due to IsolatedStorage issues when running constructor code of my UserControl’s. Looking at the code inside the constructor it was obvious that I wanted to access a few properties from my Settings class. Of course this class is not initialized in designer mode, meaning it tried to read the values from IsolatedStorage on my development machine. This caused the exceptions. At first I thought that this was a bad thing happening to me. However, it turns out that it is not bad at all that this particular error occurred. It started me thinking. It also made me realize that my ‘generic’ UserControl should not directly make use of application specific settings. After all, this would make my UserControl less generic. Instead, what I should have done is passing important settings to my UserControl from within my application. After all, the application knows when settings are available and where they are coming from, knowledge that the UserControl should not know anything about. A ‘perfect’ example of a situation where design time errors inside Visual Studio 2010 helped me to make my application better.

Windows Phone 7 and WebClient

Inspired by Rob Tiffany’s great series of articles around Windows Phone 7 Line of Business Application Development I started playing with a Windows Phone 7 Client / Azure Service combination. Since I really want to understand what is happening under the hood, my samples are usually extremely simple, yet explaining a lot about the used technology. Developing Windows Phone 7 applications however often makes me feel blind and curious. As an application developer, Windows Phone 7 appears much as a black box. Of course I know that I am running a managed application inside a Sandbox, but it would be able to sometimes take a look inside the box. Take the following scenario:

I have created a small WCF based Azure REST service. It has the following extremely simple functionality:

  • Store a single numeric value (BaseURI/setdata?number={value})
  • Retrieve the stored value (BaseURI/getdata)

I also created a Windows Phone 7 application that can used this service to store / retrieve a single number. Retrieving data from the service can be done using the following code snippet:

  1. private void GetWithLocalWebClient(object param)
  2. {
  3.     WebClient wc = new WebClient();
  4.  
  5.     wc.BaseAddress = IsDevice ? azureServerBaseAddress : localServerBaseAddress;
  6.     wc.DownloadStringCompleted +=
  7.         new DownloadStringCompletedEventHandler(wc_DownloadStringCompleted);
  8.     wc.DownloadStringAsync(new Uri("getdata", UriKind.Relative));
  9. }
  10.  
  11. void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
  12. {
  13.     WebClient wc = sender as WebClient;
  14.     if (wc != null)
  15.         wc.DownloadStringCompleted -= wc_DownloadStringCompleted;
  16.     RawRESTServiceData = e.Result;
  17. }

In this code snippet, each time the number is retrieved from the service, a new object of type WebClient is created that is used only once. The code to store a number in the cloud is very simple as well:

  1. private void SetNumber(object param)
  2. {
  3.     webClient.UploadStringAsync(
  4.         new Uri("setdata?number=" + Number, UriKind.Relative), string.Empty);
  5. }

To store a number, I am using another instance of WebClient, with a base URL set. This same instance can also be used to retrieve the number from the service, so my application has the possibility to retrieve a single number from an Azure hosted web service in different ways.

RetrieveCachedWhile testing the application, I started by retrieving the number that is currently stored in my Azure service, followed by storing a new number in the cloud and again retrieving the number that is currently stored. As you can see in the following screen dump, the last retrieval came with an unexpected result (1 instead of 3). Where did my stored number go?

It turns out that the WebClient is caching data, and it appears it does so to the extreme. Even if I create a new WebClient, it still uses cached data which is a complete surprise to me. On one hand this seems like a good thing, because it will result in less calls being made to the cloud, thus saving valuable resources. At the same time, it seems like a bad thing. What if my cloud data is updated and I still want to retrieve it through a REST call? Especially when creating a new WebClient object I think it would be reasonable to assume that a ‘real’ call will be made to my Azure service.

To resolve this potential issue, there is an easy solution. Just decorate the REST call with a unique string. Of course I don’t want to do this always, since that means that I am always physically calling out to the service. By re-using the last decorated REST call until I want to force a refresh of my data, I kind of have the best of both worlds available.

  1. private void GetCachedWithUri(object param)
  2. {
  3.     webClient.DownloadStringAsync(cachedUri);
  4. }
  5.  
  6. private void GetUncached(object param)
  7. {
  8.     cachedUri = new Uri("getdata?ticks=" + Environment.TickCount, UriKind.Relative);
  9.     webClient.DownloadStringAsync(cachedUri);
  10.     HasSavedUri = true;
  11. }

RetrieveUncached

 

Retrieving the data from the service without caching gives the expected result. Be aware though that the original cached data is still stored, so retrieving cached afterwards again gives us the original (cached) value.

 

Be aware of this behavior inside your own applications. The following video explains the caching behavior of the WebClient class in more detail:

WebClient caching behavior on Windows Phone 7

This explanation ofthe WebClient caching behavior will hopefully help you creating better Windows Phone 7 applications and save you time trying to understand what is going on behind the scenes.