Logo Subtitle Subtitle

Windows Phone Image Button

Silverlight for Windows Phone 7 has no Image Button control. Of course you can subclass an Image or create a UserControl, but it is much easier through the great Silverlight Styling & Templating. In this video I’ll show you how it’s done.

Do you want the style?

If you like the ImageButton style, just copy the following XAML to your project:

 <Style x:Key="ButtonStyleIB" TargetType="Button">
  <Setter Property="Background" Value="Transparent"/>
  <Setter Property="BorderBrush" Value="{StaticResource PhoneForegroundBrush}"/>
  <Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
  <Setter Property="BorderThickness" Value="{StaticResource PhoneBorderThickness}"/>
  <Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilySemiBold}"/>
  <Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMediumLarge}"/>
  <Setter Property="Padding" Value="10,3,10,5"/>
  <Setter Property="Template">
   <Setter.Value>
    <ControlTemplate TargetType="Button">
     <Grid x:Name="grid" Background="Transparent">
      <Grid.Projection>
       <PlaneProjection/>
      </Grid.Projection>
      <VisualStateManager.VisualStateGroups>
       <VisualStateGroup x:Name="CommonStates">
        <VisualState x:Name="Normal"/>
        <VisualState x:Name="MouseOver"/>
        <VisualState x:Name="Pressed">
         <Storyboard>
          <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentContainer">
           <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneBackgroundBrush}"/>
          </ObjectAnimationUsingKeyFrames>
          <DoubleAnimation Duration="0" To="-25" Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)" Storyboard.TargetName="grid" d:IsOptimized="True"/>
          <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.CenterOfRotationX)" Storyboard.TargetName="grid" d:IsOptimized="True"/>
         </Storyboard>
        </VisualState>
        <VisualState x:Name="Disabled">
         <Storyboard>
          <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentContainer">
           <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
          </ObjectAnimationUsingKeyFrames>
         </Storyboard>
        </VisualState>
       </VisualStateGroup>
      </VisualStateManager.VisualStateGroups>
      <ContentControl x:Name="ContentContainer" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" Margin="0" HorizontalAlignment="Center" VerticalAlignment="Center"/>
     </Grid>
    </ControlTemplate>
   </Setter.Value>
  </Setter>
 </Style>

No quote until I press space on my keyboard

I have an english version of Windows 7 installed, use dutch regional settings and I use –what I think is– a normal keyboard. One that has roughly the same layout as my first AT80286. But yesterday I re-installed my Laptop and when I type a quote (“), I don’t get a quote until I press space. Apostrophes don’t work either. Or work too good and I get two of them. People tell me this is a great feature because it allows you to put accents on characters. Like quote+e gives you ë. But I really don’t want this. I just want the character I type. Call me crazy. Just to make sure I won’t forget how to fix this for future installations, I will blog about it. Just for me ;-)

I open the regional settings, click the tab “keyboards and languages” and click Change Keyboard. This is what I see:

How I choose the correct input language:

  1. Click Add and select an english input language with keyboard US
  2. Hit OK and make the new input language the default input language
  3. Select Dutch (Netherlands) and Remove

It should look like this:

‘And” “now’ ‘all’ “my” ‘quotes work!”

Windows Phone Mahjong Solitaire video available on youtube

In my previous article about my Mahjong Solitaire, I showed a video of the game running in the emulator. Unfortunately you cannot emulate “look-and-feel” so I’ve uploaded a new video where you can see the game running on an actual device. Enjoy Mahjong Solitaire!

The version you see running is 1.4. It contains updated graphics, a completely new menu and a few bug fixes. If you have installed a previous version, please uninstall before installing 1.4. Automatic updates on the windows phone do not always work correctly.

Mahjong Solitaire is available for download at the Windows Marketplace.

Tips and tricks for building windows phone 7 applications and games

Now that I have finished the first version of my Mahjong Solitaire game, it’s time to share some things I’ve learned. Designing for the Windows Phone is very different from ASP.NET or Silverlight Apps. You have to think about tombstoning, try/buy-licences, marketplace submission and all kinds of stuff you won’t find in other online applications. This is not a tutorial or code explanation. It’s a list of things you will encounter while designing for WP7.  

1. Tombstoning (deactivate/activate)

When your application is closed (Back-button pressed, Call coming in) it is not running in the background. It’s not running at all. You need to save data when this happens. Use Application_Launching, Application_Activated, Application_Deactivated and Application_Closing to serialize and deserialize your data. I’ve used the ApplicationSettings for this: 

IsolatedStorageSettings.ApplicationSettings.Add(key, data);

My advice is to copy view model properties to a GameStateData object and serialize this object when the application is deactivated. When the application activates, you can read from the ApplicationSettings and restore the data to the view model. Restore data to the viewmodel in the App.xaml.cs! When Mainpage.OnNavigatedTo fires, your application should have a valid viewmodel and does not need to know if the viewmodel is new or restored. If you added dynamically created UIElements, you need to redraw them after your application is re-activated. 

Tombstoning is something you should do at the start of your project. Adding it later forces you to test everything all over.

2. Licence (trial/payed)

One other thing you should implement from the start, is a Licence Manager. You can write one or google them online. In Mahjong I am interested in three posibilities: 

public enum LicenceResult
    {
        Unlocked = 0,
        Trial,
        TrialExpired,
    }

I need this later for tracking events. Use the LicenseInformation class to find out if your application is a trial version:

private LicenseInformation _licenseInformation = new LicenseInformation();
.
if (_licenseInformation.IsTrial())
{
.

3. Tracking events

You will be amazed what you learn when you collect event-data from your application. I was interested in how many games were started, won, replayed. But you can also track if exceptions and other unwanted behavior occurs. The exception-details (stack-trace) is not logged. I’ll explain how to do this in the next chapter. To set up event tracking, follow these steps:

  1. If you don’t have a google account, create one.
  2. If you haven’t signed up for google analytics, do it now.
  3. Add a google analytics account and enter:
  4. Website’s URL: http://www.somedomainyouown.com/appname
  5. Accountname: appname
  6. Click Continue and enter your name and country
  7. Click Continue
  8. Agree to the terms and Create The Account.
  9. If you are asked what type of application it is, just choose a normal website.
  10. When you are finished, you will see a number like: UA-XXXXXX-X. You will need this in the next steps.
  11. Download and install the latest version of Microsoft Silverlight Analytics Framework
  12. Have a look at the demos. It’s pretty much explains itself.

In Mahjong Solitaire I never track personal information. I would not like it if my information was collected without my knowledge!

4. Error reports

If an unhandled exception occurred, I let the user choose if he or she want’s to inform me about it. I use Andy Pennell’s excellent LittleWatson for this. It uses the EMail Launcher so a user is always aware that information is being sent to you.

5. Graphics 

I have designed all my graphics in Expression Design which uses vector graphics so I can export them in all sizes. That is very handy for the application and marketplace icons.

The crispy graphics you see in Mahjong Solitaire are the direct result of the great rendering engine of Expression Design. I have exported everything to PNG.

Test your project often with different windows phone color schemes!

Testing & Submitting to Marketplace  

Take testing serious. Null-references, unhandled exceptions…test….test…test….and test more. Ask anyone to play your game or use your app. Look how they use it and check for errors.

When you are sure there are no errors in your version (but there will be!) submit it to the Marketplace. My advice is to type all the info that is asked by the APP HUB  in a text file and put it in your project. You can re-use the info for future submissions. Have images ready. Marketplace needs a 200×200, 173×173, 99×99 icon and at least one screenshot. Don’t show the phone emulator chrome in the screenshot!

Conclusion

Designing a Windows Phone game or application is fun and can be a great challenge. You have to be very comfortable with the fact you are going to ship “Work in progress”. Your first application might take a few versions before everything is stable. It made me wonder: can you image how many test hours the Nintendo team spent before shipping The Legend of Zelda: Ocarina of time?

Silverlight and windows phone application startup sounds

I created some startup sounds for a Silverlight application I’m working on and decided to share them with you. You may use the following audio files for your projects.

Audio clip: Adobe Flash Player (version 9 or above) is required to play this audio clip. Download the latest version here. You also need to have JavaScript enabled in your browser.

Audio clip: Adobe Flash Player (version 9 or above) is required to play this audio clip. Download the latest version here. You also need to have JavaScript enabled in your browser.

Audio clip: Adobe Flash Player (version 9 or above) is required to play this audio clip. Download the latest version here. You also need to have JavaScript enabled in your browser.

Audio clip: Adobe Flash Player (version 9 or above) is required to play this audio clip. Download the latest version here. You also need to have JavaScript enabled in your browser.

Audio clip: Adobe Flash Player (version 9 or above) is required to play this audio clip. Download the latest version here. You also need to have JavaScript enabled in your browser.

You can download them all in this GalaktroStartupSounds zipfile. You are free to use them any way you like. I would appreciate a link to your online application if you use them.