A two second trip into Tools->Options->Debugging|Edit and Continue to disable it will make the dialog go away. This lets you type in the editor while debugging in the emulator!

using Microsoft.Phone.Marketplace;
public LicenseInformation licenseInfo = new LicenseInformation();
private void NewGame_Click(object sender, EventArgs e) {
if (!licenseInfo.IsTrial()) {
GameFactory.CreateNewGame();
}
else {
// do something that asks to buy the product.
}
}

using Microsoft.Phone.Tasks;
public MarketplaceDetailTask detailTask = new MarketplaceDetailTask();
private void buy_now_Click(object sender, RoutedEventArgs e){
detailTask.Show();
}
For the “Buy Now” button behavior described in our example, your code might look something like this:


using Microsoft.Phone.Tasks;
using System.IO.IsolatedStorage;
namespace NineLettuce {
internal static class TrialManager {
#if DEBUG
private const string LicenseFileName = "DebugFullLicense.txt";
#endif
public static bool IsTrial {
get {
#if DEBUG
System.Threading.Thread.Sleep(60); // simulate delay of IsTrial() call
// check if we have a license on the app.
IsolatedStorageFile myStore = IsolatedStorageFile.GetUserStoreForApplication();
return !(myStore.FileExists(LicenseFileName));
#else
// in release use the real APIs
LicenseInformation licenseInfo = new LicenseInformation();
return licenseInfo.IsTrial();
#endif
}
}
public static void ShowMarketplace() {
MarketplaceDetailTask detailTask = new MarketplaceDetailTask();
detailTask.Show();
#if DEBUG
// if tombstoning occurs, write out a file so
// we can test getting past trial mode
IsolatedStorageFile myStore
= IsolatedStorageFile.GetUserStoreForApplication();
myStore.CreateFile(LicenseFileName);
#endif
}
public static void ResetTrial() {
#if DEBUG
// function for clearing off the license
IsolatedStorageFile myStore
= IsolatedStorageFile.GetUserStoreForApplication();
if (myStore.FileExists(LicenseFileName)) {
myStore.DeleteFile(LicenseFileName);
}
#endif
}
}
}
Conclusions
Keep the buying experience simple, you don't need to navigate places to have a good experience in purchasing. If I had my druthers I would have put the new game button on the first page so it was more obvious.
If you want to do more elaborate things than I have done, you can use the IsolatedStorageFile solution to remember session state. If IsTrial() is false, and you've got something scribbled in a file, then you know you can show a particular screen or advance to a particular level.
I hope that as time goes on the developer experience in this area improves, as even with this solution it is still difficult to know what the experience will be when the app hits the store!
Related reads: Nine Lettuce, Beware the Loaded Event, Tech-Ed Video, How to Implement the Trial Experience in a Windows Phone Application, How to Test and Debug the Trial APIs

<controls:Panorama Title="nine lettuce" Name="panoramaControl">
<!--[1] Create an empty panorama item -->
<controls:PanoramaItem Name="gameItem"
Loaded="GameScreen_Loaded" Header="games"/>
<controls:Panorama/>
private void GameScreen_Loaded(object sender, RoutedEventArgs e) {
// [2] sync the loaded event, but defer the
// load until later
Dispatcher.BeginInvoke(new Util.MethodInvoker(LoadGameScreen));
}
private void LoadGameScreen() {
// [3] create the game screen user control
GameScreen game = new GameScreen();
// [4] put it into the PanoramaItem created in step [1]
gameItem.Content = game;
}
// handy utility method if you don’t
// like anonymous delegate syntax in step [2]
internal static class Util {
public delegate void MethodInvoker();
}
public partial class GameScreen : UserControl {
public GameScreen() {
InitializeComponent();
this.Unloaded += new RoutedEventHandler(Game_Unloaded);
// [1] Bug – this does not get called after the
// back button is pressed giving us an object
// where the unloaded code has run and undone
// what we did in the constructor.
GameFactory.GameViewModelChanged +=
GameFactory_GameViewModelChanged;
}
void Game_Unloaded(object sender, RoutedEventArgs e) {
// [2] unsubscribing from a static event
// to avoid memory leaks...
GameFactory.GameViewModelChanged -=
GameFactory_GameViewModelChanged;
}
}
[2] The code in Unloaded disconnects the object from the GameViewModelChanged event.
When the game is resumed, the code in [1] is not called.
public partial class GameScreen : UserControl {
public GameScreen() {
InitializeComponent();
this.Loaded += new RoutedEventHandler(Game_Loaded);
this.Unloaded += new RoutedEventHandler(Game_Unloaded);
}
void Game_Loaded(object sender, RoutedEventArgs e) {
// [1] Fixtit! make sure your loaded
// and unloaded handlers match each other –
// if unloaded unsubscribes, make loaded subscribe.
GameFactory.GameViewModelChanged +=
GameFactory_GameViewModelChanged;
}
void Game_Unloaded(object sender, RoutedEventArgs e) {
GameFactory.GameViewModelChanged -=
GameFactory_GameViewModelChanged;
}
}
[1] - now the event handler will be hooked back up when our app is resuming.
This is totally unscientific as I had a sample group of 5 people...