wp7appdevelopment

Adventures in Windows Phone app development

Tag Archives: Windows Phone

Tombstoning in Windows Phone 8 Apps

I have a simple Windows Phone game, and my way of dealing with tombstoning is to just start a new game. To do this, I need to first detect that that app was tombstoned. I check for this every time I navigate to a page. If tombstoning has occurred, I navigate to the main page of my app/game and delete the navigation back stack, effectively starting fresh.

NOTE: Because my game is so simple, I don’t need to bother with saving the game state or any data. Most apps will want to save info instead of just starting a new game.

[1] Create a entry in the isolated storage to store a boolean value of whether the app has been tombstoned.

I use a helper class, AppSettings, to store and retrieve values from Isolated Store. See this post for more info. The default value is false.

const string WasTombstonedKeyName = "WasTombstoned";
const bool WasTombstonedDefault = false;
 public bool wasTombstoned
        {
            get
            {
                return GetValueOrDefault<bool>(WasTombstonedKeyName, WasTombstonedDefault);
            }
            set
            {
                AddOrUpdateValue(WasTombstonedKeyName, value);
                Save();
            }
        }

[2] You can check if an app has been activated in the Application_Activated() method of App class (App.xaml.cs). This method is executed when an application is activated (brought to the foreground). It does not execute when the application is first launched.

Add the following code to set the value of our WasTombstoned flag in the (isolated store) to either true or false:

 private void Application_Activated(object sender, ActivatedEventArgs e)
        {
            AppSettings mySettings = new AppSettings();

            if (e.IsApplicationInstancePreserved)
                mySettings.WasTombstoned = false;
            else
                mySettings.WasTombstoned = true;
        }

[3] Modify the OnNavigatedTo method of your MainPage.xaml.cs. You’ll want to clear the WasTombstoned flag, and also clear the navigation backstack.

 protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            // Remove entries from the backstack, so that a back key press exits the app.
            try
            {
                while (NavigationService.CanGoBack)
                    NavigationService.RemoveBackEntry();
            }
            catch
            {
            }

            // clear the wasTombstoned flag
            mySettings.wasTombstoned = false;

            base.OnNavigatedTo(e);
        }

[4] On all other pages, edit the OnNavigatedTo method to check for Tombstoning and return to the MainPage if it occurred.

 protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            AppSettings myAppSettings = new AppSettings();

            base.OnNavigatedTo(e);

            if (myAppSettings.wasTombstoned)
                NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));
        }

[5] Testing
Assuming you are using Visual Studio to build your app, the easiest way to test tombstoning is to edit the Properties:

  1. In the Solution Explorer, double-click on Properties to open that panel.
  2. Left-click on the Debug tab (left side of panel).
  3. Click the checkbox for “Tombstone upon deactivation while debugging.”

Now, when you are testing, when you leave the application (for example, when you press the windows key or search key on the bottom of the phone) and then return to the application (for example, by pressing the back key), the application will have been tombstoned.

Create a Windows Phone tile with no title displayed

You can have the tile for your Windows Phone app be displayed with a blank title. This is useful if your image already contains the app title.

The only trick: you can’t directly delete the title in the ‘property editing’ mode of the Visual Studio project. Instead, edit the WMAppManifest.xml file directly to remove the title. Just remove the title between the tags. The project will still compile, and this won’t stop your app from getting approved.

<TemplateType5>
    <BackgroundImageURI ... ... ...>Background.png</BackgroundImageURI>
    <Count>0</Count>
    <Title></Title>   <-- leave this blank -->
</TemplateType5>

That’s it. Visual Studio thinks this field cannot be empty, but it can. Edit the XML file directly, and you’re good to go.

Scrolling to the Selected Item Listbox

If you’re developing an Windows Phone app, you will often use a ListBox to display information. Here’s how to set the selected item programmatically and scroll the selected item into view. This example assumes you’re working with C# and Silverlight.

Selecting an item in a listbox

You can select a specific item in a ListBox using the SelectedIndex property. For example, to select the sixth item (index=5) in a list, use the following in your C# code:

  myList.SelectedIndex = 5;

Scrolling Selected Item into View

The ListBox.ScrollIntoView method can be used to scroll to a particular place in a ListBox. For example, to scroll down your ListBox items so that the selected item is displayed, use the following in your C# code:

   myList.ScrollIntoView(myList.SelectedItem);

One note — if you’ve changed the contents of your ListBox (i.e., if the contents of your ItemsSource collection changes), you may need to call UpdateLayout() before calling ScrollIntoView():

   UpdateLayout();
   myList.ScrollIntoView(myList.SelectedItem);

References

ListBox.ScrollIntoView Method

ListBox Class

How to Make a Windows Phone 7 Vibrate (C#)

Vibrate your phone?

There are many reasons you might want to programmatically vibrate the phone during apps or games.  You might want to alert the user to an error condition, and emphasize that a button has been clicked.

The Windows Phone 7 SDK makes it easy for developers to control the vibrate function easily, using the VibrateController class. The VibrateController class is defined in the namespace Microsoft.Devices.

The following example shows how to vibrate the phone using C#:


using Microsoft.Devices;

VibrateController vibrate = VibrateController.Default;
vibrate.Start(TimeSpan.FromMilliseconds(200));

That’s all that you need to do! You can change the vibrate duration — this example uses 200 milliseconds.
Of course, common-sense best practices: don’t overdo the use of vibration, and give the user the option to disable.

References

VibrateController class documentation

Displaying Your Ads as a Fallback for Microsoft pubCenter

Microsoft pubCenter currently seems to be the best choice for monetizing apps on the Windows Phone. But all too often, pubCenter’s inventory is too low and it fails to serve an ad for your app.  You can detect when an error occurs displaying an ad, and display your ad banner instead.  This way, your app will display pubCenter ads when it can; and when it can’t, it will fall back to displaying your ad.

The key is to create a banner that’s the same size as the pubCenter ad control, and set its visibility to Collapsed. In the code behind, you need to add event handlers for ErrorOccurred and AdRefreshed. In the ErrorOccurred event handler, which is called when pubCenter is unable to serve an ad, you’ll collapse the Microsoft ad control and set your ad to visible. In the AdRefreshed event handler, which is called when pubCenter successfully servers an ad, you’ll do the opposite: collapse your ad and set the Microsoft ad control to visible.

In the Xaml

You can place both controls in a StackPanel. Or, place in the same location, like the same Grid Row/Column. Just be sure to collapse your control.

    xmlns:my="clr-namespace:Microsoft.Advertising.Mobile.UI;assembly=Microsoft.Advertising.Mobile.UI"
    <my:AdControl Name="adControl1" Grid.Row="0" Height="80" Width="480"
        HorizontalAlignment="Left" Margin="0"  VerticalAlignment="Top"
        AdUnitId="YOUR_ID" ApplicationId="YOUR_APP_ID"/>
    <Border Name="MyAdBorder" Grid.Row="0" Height="80" Width="480" VerticalAlignment="Top"
        Background="WhiteSmoke" Visibility="Collapsed">
        <!-- whatever you want to display in your ad -->
    </Border>

In the Code Behind

Modify your class constructor, and attach the event handlers to pubCenter control events. Depending on the result of the pubCenter request, either your ad or the pubCenter ad control is collapsed and the other one is displayed.

    using Microsoft.Advertising.Mobile;
    public MainPage()
    {
        InitializeComponent();

         adControl1.ErrorOccurred += new EventHandler<Microsoft.Advertising.AdErrorEventArgs>(adControl1_ErrorOccurred);
         adControl1.AdRefreshed += new EventHandler(adControl1_AdRefreshed);
    }

        // An ad was successfully displayed; hide our advertising banner
        void adControl1_AdRefreshed(object sender, EventArgs e)
        {
            MyAdBorder.Visibility = System.Windows.Visibility.Collapsed;
            adControl1.Visibility = System.Windows.Visibility.Visible;
        }

        // error displaying AdCenter ad; show our advertising banner
        void adControl1_ErrorOccurred(object sender, Microsoft.Advertising.AdErrorEventArgs e)
        {
            MyAdBorder.Visibility = System.Windows.Visibility.Visible;
            adControl1.Visibility = System.Windows.Visibility.Collapsed;
        }

NOTE: pubCenter visually hides the ad control when there’s no ad to display. But relying on this alone won’t work! Even though nothing displays, it still occupies the space and catches all taps, making any controls in your ad unclickable. The key is to explicitly set the control’s visual state to Collapsed.

Adding Tilt Effect to Windows Phone Apps

You can use the Tilt Effect in your Windows Phone apps to give the user additional visual feedback that a control has been pressed. The easiest way to start using it is to download the Microsoft Phone Controls Toolkit  and then enable it for each page in your application. You can also enable only certain controls, or suppress it for selected controls.

Note: the Tilt Effect is now integrated into the Silverlight for Windows Phone Toolkit (Feb 2011 release).

  1. Download the Silverlight for Windows Phone Toolkit from CodePlex. Or, use NuGet to add the package to your Visual Studio project.
  2. Add a reference to your Visual Studio project (NuGet does this for you automatically):
    Microsoft.Phone.Controls.Toolkit
  3.  Add the following to the .xaml file for each Page in your app:
    xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
    toolkit:TiltEffect.IsTiltEnabled="True"
    

That’s it!

Note: by default, the tilt effect only works with general ButtonBase and ListBoxItem controls. However, you can apply this effect to other controls by adding them to the TiltableItems list:

TiltEffect.TiltableItems.Add(typeof("MyCustomControl"))

References:

Silverlight: Page Transitions

The following is a high-level overview of how to add page transitions to your Windows Phone Silverlight application. If you need more step-by-step directions, see this article.

  1. Download the Silverlight Toolkit for Windows Phone from Codeplex (here) or use NuGet to add the package to your Visual Studio project.
  2. Add a reference to Microsoft.Phone.Controls to your project.
  3. Edit the App.xaml.cs file, and modify the InitializePhoneApplication() method so that RootFrame is of type TransitionFrame:
        RootFrame = new TransitionFrame();
        //RootFrame = new PhoneApplicationFrame();
    
  4. Add the following to all XAML files:
    xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
    
  5.  Add the following definition to the Application.Resources element in your App.xaml file. You can then reuse this style on each of your target pages. This example defines a turnstile page transition. See belowfor other transition options.
    <Application.Resources>
                <Style x:Key="TransitionPageStyle" TargetType="phone:PhoneApplicationPage">
                    <Setter Property="toolkit:TransitionService.NavigationInTransition">
                        <Setter.Value>
                            <toolkit:NavigationInTransition>
                            <toolkit:NavigationInTransition.Backward>
                                <toolkit:TurnstileTransition Mode="BackwardIn"/>
                            </toolkit:NavigationInTransition.Backward>
                            <toolkit:NavigationInTransition.Forward>
                                <toolkit:TurnstileTransition Mode="ForwardIn"/>
                            </toolkit:NavigationInTransition.Forward>
                        </toolkit:NavigationInTransition>
                    </Setter.Value>
                    </Setter>
                    <Setter Property="toolkit:TransitionService.NavigationOutTransition">
                        <Setter.Value>
                            <toolkit:NavigationOutTransition>
                            <toolkit:NavigationOutTransition.Backward>
                                <toolkit:TurnstileTransition Mode="BackwardOut"/>
                            </toolkit:NavigationOutTransition.Backward>
                            <toolkit:NavigationOutTransition.Forward>
                                <toolkit:TurnstileTransition Mode="ForwardOut"/>
                            </toolkit:NavigationOutTransition.Forward>
                        </toolkit:NavigationOutTransition>
                    </Setter.Value>
                    </Setter>
                </Style>
    </Application.Resources>
    

    NOTE: if you want some pages to have different page transitions, you can define multiple styles in the App.xaml. Or you can define the transition on each XAML page rather than defining a style in App.xaml.

In each of your XAML files (phone application pages), add the following style declaration:

<phone:PhoneApplicationPage
x:Class="MyTransitionsProject.MainPage"
...
Style="{StaticResource TransitionPageStyle}">

Transition Options

Swivel  Slide  Rotate  Turnstile
  • FullScreenIn
  • FullScreenOut
  • ForwardIn
  • ForwardOut
  • BackwardIn
  • BackwardOut
  • SlideUpFadeOut
  • SlideDownFadeIn
  • SlideDownFadeOut
  • SlideLeftFadeIn
  • SlideLeftFadeOut
  • SlideRightFadeIn
  • SlideRightFadeOut
  • In90Clockwise
  • In90Counterclockwise
  • In180Clockwise
  • In180Counterclockwise
  • Out90Clockwise
  • Out90Counterclockwise
  • Out180Clockwise
  • Out180Counterclockwise
  • ForwardIn
  • ForwardOut
  • BackwardIn
  • BackwardOut

References:

Silverlight: Sound Effects

The following procedure can be used to add sound effects to Windows Phone 7 (WP7) apps developed with Silverlight/C#.

  1. Add a reference to Microsoft.Xna.Framework to your project
  2. Add the .wav files to your project and specify type=Content
  3. Add the following statements to your C# code:
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Audio;
    using System.Windows.Resources;
    using System.Windows.Threading;
    
  4. Add variables for your SoundEffects:
    private SoundEffect mySound;
    
  5. Add the following code to the page (class) constructor:
    
    LoadSound("Sounds/mySound.wav", out mySound);
    // Timer to simulate the XNA game loop (SoundEffect classes are from the XNA Framework)
    DispatcherTimer XnaDispatchTimer = new DispatcherTimer();
    XnaDispatchTimer.Interval = TimeSpan.FromMilliseconds(50);
    
    // Call FrameworkDispatcher.Update to update the XNA Framework internals.
    XnaDispatchTimer.Tick += delegate { try { FrameworkDispatcher.Update(); } catch { } };
    // Start the DispatchTimer running.
    XnaDispatchTimer.Start();
    
    
  6. Add the following LoadSound method:
            private void LoadSound(String SoundFilePath, out SoundEffect Sound)
            {
                // For error checking, assume we'll fail to load the file.
                Sound = null;            try
                {
                    // Holds informations about a file stream.
                    StreamResourceInfo SoundFileInfo = App.GetResourceStream(new Uri(SoundFilePath,
                            UriKind.Relative));                // Create the SoundEffect from the Stream
                    Sound = SoundEffect.FromStream(SoundFileInfo.Stream);
                }
                catch (NullReferenceException)
                {
                    // Display an error message
                    MessageBox.Show("Couldn't load sound " + SoundFilePath);
                }
            }
    
  7. Add the following code to play the sound effect:
                try
                {
                    mySound.Play();
                }
                catch (NullReferenceException)
                {
                   MessageBox.Show("Can't play, cardSound is null.");
                }
    

    Simpler Example: No timer

    If the only XNA framework functionality used inside a Silverlight application is one or more instance of type SoundEffect, and only one single SoundEffect is played at any given time, you don’t need to set up a timer. Instead, you can just call FrameworkDispatcher.Update() before calling the Play() method.

    For example:

    
    try
    {
    FrameworkDispatcher.Update();
    mySound.Play();
    }
    catch (NullReferenceException)
    {
    MessageBox.Show("Can't play, cardSound is null.");
    }
    

    Complete Example

    The following example puts all the bits of code together. It assumes the app has the single page, MainPage.xaml, with a button that uses the Button_Click callback method. It also assumes there is a sound file named “UI_Misc15.wav” that is stored in a project subdirectory “Sounds”.
    using System;
    using System.Windows;
    using Microsoft.Phone.Controls;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Audio;
    using System.Windows.Resources;
    using System.Windows.Threading;
    
    namespace SoundDemo
    {
        public partial class MainPage : PhoneApplicationPage
        {
            private SoundEffect mySound;
    
            // Constructor
            public MainPage()
            {
                InitializeComponent();
    
                LoadSound("Sounds/UI_Misc15.wav", out mySound);
    
                // Timer to simulate the XNA game loop (SoundEffect classes are from the XNA Framework)
                DispatcherTimer XnaDispatchTimer = new DispatcherTimer();
                XnaDispatchTimer.Interval = TimeSpan.FromMilliseconds(50);
    
                // Call FrameworkDispatcher.Update to update the XNA Framework internals.
                XnaDispatchTimer.Tick += delegate { try { FrameworkDispatcher.Update(); } catch { } };
    
                // Start the DispatchTimer running.    
                XnaDispatchTimer.Start();
    
            }
    
            private void LoadSound(String SoundFilePath, out SoundEffect Sound)
            {
                // For error checking, assume we'll fail to load the file.
                Sound = null;
    
                try
                {
                    // Holds informations about a file stream.
                    StreamResourceInfo SoundFileInfo = App.GetResourceStream(new Uri(SoundFilePath,
                            UriKind.Relative));
    
                    // Create the SoundEffect from the Stream
                    Sound = SoundEffect.FromStream(SoundFileInfo.Stream);
                }
                catch (NullReferenceException)
                {
                    // Display an error message
                    MessageBox.Show("Couldn't load sound " + SoundFilePath);
                }
            }
    
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                try
                {
                    mySound.Play();
                }
                catch (NullReferenceException)
                {
                    MessageBox.Show("Can't play, cardSound is null.");
                }
    
            }
        }
    }
    

How to Advertise on Windows Phone

What I thought was a simple question took me some research. Why doesn’t Microsoft make it easier to find out how to advertise on their Windows Phone?

First, you need to create an account on Microsoft Advertising adCenter. Search the web before signing up — you may be able to score some free advertising credits for new accounts. (If you do get a promotional credit, enter it on the Accounts&Billing tab in adCenter.)

Once your account is set up and billing information is added, you can create your ad campaigns, ads, and keywords. Now, to get these ads into Windows Phone apps, you’ll need to set the targeting options and ad distribution correctly. You can do this at either the campaign or ad group level. You also need to specify that you want your ads to be displayed on the content network (not search).

  1. In your campaign or ad group settings, go to the Targeting Options/Advanced Targeting options. Expand Device, and select “Smartphone and other mobile devices with full browsers”. Deselect all others.
  2. At the end of that line, you’ll see “All OS | Edit”. Click Edit.
  3. Select Windows, and deselect all others (Android, iOS, etc.).
  4. Under Advanced Settings, expand Ad Distribution: Deselect Search network and select content network.
  5. Save your changes.

Now your ads will go in the Microsoft Advertising inventory and will be displayed in the appropriate Windows Phone apps. The ads are served using the same process as other content ads: your keywords are matched to apps using keywords, the app description, and the app category.

This is how you can get text ads displaying on Windows Phone. If you want to have a display ad on the Windows Phone, you need to go through Microsoft’s sales team. You can get in touch with them here: https://advertising.microsoft.com/contact-sales.

Using PhotoChooserTask in Silverlight/Windows Phone apps

The PhotoChooserTask launches an app that lets the user select a photo from their phone. If the user selects a photo, the app raises the Completed event and the event handler gets passes a PhotoResult object. You can access the image data through this object’s photo image stream.

    1. Include a using statement for Microsoft.Phone.Tasks in your page class (e.g, MainPage.xaml.cs):
      using Microsoft.Phone.Tasks;
    2. In your page class, include a declaration for a PhotoChooserTask:
       PhotoChooserTask photoChooserTask;
    3. In the constructor, initialize the PhotoChooserTask and add the handler for the Completed event:
      photoChooserTask = new PhotoChooserTask(); 
      photoChooserTask.Completed += new EventHandler<PhotoResult>(photoChooserTask_Completed);
    4. Add the Completed handler:
      // The Completed event handler. In this example, a new BitmapImage is created and  
      // the source is set to the result stream from the PhotoChooserTask
      void photoChooserTask_Completed(object sender, PhotoResult e)
          {
              if (e.TaskResult == TaskResult.OK) {
                  System.Windows.Media.Imaging.BitmapImage bmp =
                     new System.Windows.Media.Imaging.BitmapImage(); 
                  bmp.SetSource(e.ChosenPhoto);
              }
          }
    5. Add a method to call the PhotoChooserTask. This examples assumes the task will be called after a button click:
      // In this example, the PhotoChooserTask is shown in response to a button click
      private void button1_Click(object sender, RoutedEventArgs e)
      {
          try {
              photoChooserTask.Show();
          }
          catch (System.InvalidOperationException ex) {
              // Catch the exception, but no handling is necessary.
          }
      }

Note: if the PhotoChooserTask looks like it’s not working on the device but it works fine on the emulator, disconnect your phone from the Zune software. If you’re debugging while the Zune software is running, the task will return the Cancel event and never display the photo chooser.

Complete Code Sample

public partial class MainPage : PhoneApplicationPage
{
    // Declare the PhotoChooserTask object with page scope.
    PhotoChooserTask photoChooserTask;

    // Constructor
    public MainPage()
    {
        InitializeComponent();

        // Initialize the PhotoChooserTask and assign the Completed handler in the page constructor.
        photoChooserTask = new PhotoChooserTask();
        photoChooserTask.Completed += new EventHandler<PhotoResult>(photoChooserTask_Completed);
    }

    // In this example, the PhotoChooserTask is shown in response to a button click
    private void button1_Click(object sender, RoutedEventArgs e)
    {
        try {
            photoChooserTask.Show();
        }
        catch (System.InvalidOperationException ex) {

           // Catch the exception, but no handling is necessary.
        }
    }

    // The Completed event handler. In this example, a new BitmapImage is created and
    // the source is set to the result stream from the PhotoChooserTask
    void photoChooserTask_Completed(object sender, PhotoResult e)
    {
        if (e.TaskResult == TaskResult.OK) {
            System.Windows.Media.Imaging.BitmapImage bmp =
                new System.Windows.Media.Imaging.BitmapImage();
            bmp.SetSource(e.ChosenPhoto);
         }
    }
}

Additional References