Monthly Archives: March 2014

WinRT Contact Picker

One of the best features of Windows 8 is that it allows you to store all your contacts in one place. This means you can link your e-mail, Linked-in, Facebook, Twitter and Google+ contacts in a single list. If you want to access this programatically, it’s surprisingly simple.

The first thing to do is to create a contact picker

        // Create the picker
        var picker = new Windows.ApplicationModel.Contacts.ContactPicker();
        picker.commitButtonText = "Select" ;

The commitButtonText allows you to say what the dialog’s OK button will say. The next function is called to make the contact selection. In Windows 8 this was pickMultipleContactsAsync (there was also a pickSingleContactAsync), but both are deprecated for 8.1, and you should use the following:

     // Open the picker for the user to select contacts
     picker.pickContactsAsync();

Or

     // Open the picker for the user to select a contact
     picker.pickContactAsync();

This needs to be inside a promise, to ensure that the app doesn’t become unresponsive while you select contacts:

    function pickContacts() {

         // Create the picker
        var picker = new Windows.ApplicationModel.Contacts.ContactPicker();
        picker.commitButtonText = "Select";

        var emailsPromise = new WinJS.Promise( function (complete, error, progress) {

            // Open the picker for the user to select contacts
            picker.pickContactsAsync().then( function (contacts) {
                if (contacts.length > 0) {
                    // Iterate through the contacts collection and do something
                    
                    complete(); // Call complete to exit the promise
                } else {
                    complete(); // Call complete to exit the promise
                }
            });
        });

        return emailsPromise;
    };

This works, with one slight caveat – it gives you every single contact. But say you just want the e-mail address? The following will return only the contacts for which you have an e-mail address:

         picker.desiredFieldsWithContactFieldType.append(Windows.ApplicationModel.Contacts.ContactFieldType.Email);

(Note, this replaces the deprecated desiredFields property in Windows 8.0)

So, the final cut looks like this:

    function pickContacts() {

         // Create the picker
        var picker = new Windows.ApplicationModel.Contacts.ContactPicker();
        picker.commitButtonText = "Select";
        picker.desiredFieldsWithContactFieldType.append(
               Windows.ApplicationModel.Contacts.ContactFieldType.Email);

        var emailsPromise = new WinJS.Promise( function (complete, error, progress) {

            // Open the picker for the user to select contacts
            picker.pickContactsAsync().then( function (contacts) {
                if (contacts.length > 0) {
                    // Iterate through the contacts collection and do something
                    
                    complete(); // Call complete to exit the promise
                } else {
                    complete(); // Call complete to exit the promise
                }
            });
        });

        return emailsPromise;
    };

So, what does this look like in C#? IMHO, it looks a lot neater:

             // Create the picker
            Windows.ApplicationModel.Contacts. ContactPicker picker = new Windows.ApplicationModel.Contacts.ContactPicker ();
            picker.CommitButtonText = "Select";
            picker.DesiredFieldsWithContactFieldType.Add(
               Windows.ApplicationModel.Contacts. ContactFieldType .Email);

            // Open the picker for the user to select contacts
            var contacts = await picker.PickContactsAsync();
            if (contacts.Count() > 0)
            {
                //...
            }

Final Note

It’s also worth noting that when you get the contacts, the e-mail addresses for each are a collection (each contact can have many); so you’ll need to do something like this:

contacts.forEach( function (contact) {
    contact.emails.every( function (email) { output += email.address + "," ; });
});

Or

foreach( var em in c.Emails)
{
    System.Diagnostics. Debug.WriteLine( "{0} email {1}" , c.Name, em.Address);
}

Using data binding inside monogame to control ad control display

I’ve already blogged a few times on using monogame with XAML. One thing that occurred to me recently was that I could leverage this in order to better control when the ad control appears in one of my games. Basically, my idea was that I could bind the main game page to a model, which determined whether the ad would be displayed.

Obviously, the difficulty here is that you need to pass the view model around your app. Monogame doesn’t seem to be very good at allowing you to do that, so I decided to use this approach (in app.xaml.cs):

    sealed partial class App : Application
    {
        private static GamePageViewModel _gamePageViewModel;
        public static GamePageViewModel GamePageViewModel
        {
            get
            {
                if (_gamePageViewModel == null)
                {
                    _gamePageViewModel = new GamePageViewModel();
                }

                return _gamePageViewModel;
            }
        }

A couple of notes on that code:
1. Yes, I could have simply instantiated the viewmodel at the start of the app.
2. Yes, it is static. This is so you can access it elsewhere.

The GamePageViewModel isn’t particularly noteworthy:

namespace MyGame.ViewModel
{
    public class GamePageViewModel : INotifyPropertyChanged
    {
        private bool _showAds;
        public bool ShowAds
        {
            get { return _showAds; }
            set
            {
                _showAds = value;
                RaisePropertyChanged( "ShowAds");
            }
        }

        private void RaisePropertyChanged( string caller)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged( this, new PropertyChangedEventArgs(caller));
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }
}

I do need to set this in code though; so when you display the GamePage:

         protected override void OnLaunched( LaunchActivatedEventArgs args)
        {
            var gamePage = Window.Current.Content as GamePage;

            // Do not repeat app initialization when the Window already has content,
            // just ensure that the window is active
            if (gamePage == null)
            {
                // Create a main GamePage
                gamePage = new GamePage(args.Arguments);

                // Set the DataContext to the static instance of the ViewModel
                gamePage.DataContext = App.GamePageViewModel;

You need to bind the ad control (use somthing like this – I haven’t detailed the code for the converter, but I’m sure 3 seconds of Internet searching will reveal a few thousand examples):

               
<UI: AdControl x: Name ="adControl"                                          
ApplicationId ="appid"
      AdUnitId ="appunitid"      
Width ="728"
      Height ="90"
      IsAutoRefreshEnabled ="True"                         
      Margin ="5"      
      Visibility ="{Binding ShowAds , Converter ={StaticResource BoolToVisibilityConv}}">
/>

What this allows me to do, from ANYWHERE in the game is this:

               
         private async static void purchaseCommandInvoked(Windows.UI.Popups.IUICommand command)
        {
            bool success = await License.PurchaseApp();

            if (success)
            {
                // Updating the view model here!
                App.GamePageViewModel.ShowAds = false;
            }
        }

Conclusion

So, nothing new here, but using binding inside Monogame didn’t occur to me immediately, so there must be a least some people in the same boat.

Convert Monogame to Monogame with XAML

Some time ago, I blogged about the importance of creating a “Monogame With XAML” project. Before I’d written this, I’d started a long running project, and realised that I needed XAML (for reasons already indicated). So, is it possible to convert? YES!

Is it easy? Actually, it’s not too bad; but to save anyone else (and my future self) the hastle of working out how, I’ve broken it down into 7 easy steps. (Below, MyGame refers to your game namespace).

1. Add app.xaml as a blank xaml page. Once it’s added, change the BuildAction to ApplicationDefinition:

Image

2. Clear the XAML from the page, and replace with the following:

<Application
    x: Class="MyGame.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns: x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns: local="using:MyGame">

    <Application.Resources >
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>

                <!--
                    Styles that define common aspects of the platform look and feel
                    Required by Visual Studio project and item templates
                 -->
                <ResourceDictionary Source ="Common/StandardStyles.xaml"/>
            </ResourceDictionary.MergedDictionaries>

        </ResourceDictionary>
    </Application.Resources >
</Application>

3. StandardStyles.xaml referenced above will not exist. Create a new XAML file in the appropriate directory (the one in this example is in a Common subdirectory. This should look something like the following (although given that these are styles, you may have different ideas):

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <!-- Non-brush values that vary across themes -->

    <ResourceDictionary.ThemeDictionaries>
        <ResourceDictionary x:Key="Default">
            <x:String x:Key="BackButtonGlyph">&#xE071;</x:String>
            <x:String x:Key="BackButtonSnappedGlyph">&#xE0BA;</x:String>
        </ResourceDictionary>

        <ResourceDictionary x:Key="HighContrast">
            <x:String x:Key="BackButtonGlyph">&#xE071;</x:String>
            <x:String x:Key="BackButtonSnappedGlyph">&#xE0C4;</x:String>
        </ResourceDictionary>
    </ResourceDictionary.ThemeDictionaries>

    <x:String x:Key="ChevronGlyph">&#xE26B;</x:String>
...
</ResourceDictionary>

If you’re unsure about what to put in here then just create a blank store app and lift this file.

4. Next, you need to edit the code behind for the new App.Xaml file. In App.Xaml.cs, you should have the following code:

using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.UI.Xaml;

// The Blank Application template is documented at http://go.microsoft.com/fwlink/?LinkId=234227

namespace MyGame
{
    /// <summary>
    /// Provides application-specific behavior to supplement the default Application class.
    /// </summary>
    sealed partial class App : Application
    {
        /// <summary>
        /// Initializes the singleton application object.  This is the first line of authored code
        /// executed, and as such is the logical equivalent of main() or WinMain().
        /// </summary>
        public App()
        {
            InitializeComponent();
            Suspending += OnSuspending;
        }

        /// <summary>
        /// Invoked when the application is launched normally by the end user.  Other entry points
        /// will be used when the application is launched to open a specific file, to display
        /// search results, and so forth.
        /// </summary>
        /// <param name="args">Details about the launch request and process.</param>
        protected override void OnLaunched(LaunchActivatedEventArgs args)
        {
            var gamePage = Window.Current.Content as GamePage;

            // Do not repeat app initialization when the Window already has content,
            // just ensure that the window is active
            if (gamePage == null)
            {
                // Create a main GamePage
                gamePage = new GamePage(args.Arguments);

                if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)
                {
                    // TODO: Load state from previously suspended application
                }

                // Place the GamePage in the current Window
                Window.Current.Content = gamePage;
            }

            // Ensure the current window is active
            Window.Current.Activate();
        }

        /// <summary>
        /// Invoked when application execution is being suspended.  Application state is saved
        /// without knowing whether the application will be terminated or resumed with the contents
        /// of memory still intact.
        /// </summary>
        /// <param name="sender">The source of the suspend request.</param>
        /// <param name="e">Details about the suspend request.</param>
        private void OnSuspending(object sender, SuspendingEventArgs e)
        {
            var deferral = e.SuspendingOperation.GetDeferral();

            // TODO: Save application state and stop any background activity

            deferral.Complete();
        }
    }
}

5. GamePage referenced above doesn’t exist; create a new Page, called GamePage.xaml, and paste the following Xaml into it:

<SwapChainBackgroundPanel
    x:Class="MyGame.GamePage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MyGame"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid>
    </Grid>

</SwapChainBackgroundPanel>

6. Next, press F7 to get to the code-behind for GamePage.Xaml. In GamePage.Xaml.cs, paste the following code:

    public sealed partial class GamePage : SwapChainBackgroundPanel
    {
        readonly GameEngine _game;

        public GamePage(string launchArguments)
        {
            this.InitializeComponent();

            // Create the game.
            _game = XamlGame<GameEngine>.Create(launchArguments, Window.Current.CoreWindow, this);
        }
    }

This should link the whole thing back to your initial GameEngine that MonoGame uses.

7. Finally, locate Program.cs and either comment out the code, or just delete it.

DONE

You should now find that your game runs exactly as before, except you now have XAML capabilities.

Please feel free to add any comments for anything that I might have missed, or improvements you may have on this process. Also, feel free to leave comments such as: “Yes, this worked!”.