Development, MVVM, Open Source, Videos, Windows, Windows 8

Microsoft DevRadio: Community Corner – Update Controls for Windows 8 app Development

This entry is part 2 of 3 in the series Dev Radio: Community Corner

I recently had the  pleasure  to interview wicked smart Microsoft Client App Dev MVP Michael Perry as part of the Microsoft DevRadio show to hear about the amazing work he’s done on an open source databinding framework called  Update Controlswhich can help Windows 8 app developers simplify their code by automatically discovering dependencies so that you won’t have to manage them in your view model.

Next Steps:

Subscribe to the podcast via iTunes, Zune, or RSS

If you’re interested in learning more about the products or solutions discussed in this episode, click on any of the below links for free, in-depth information:

Websites:

Videos:

Virtual Labs:

Download

Azure, Cloud, Development, MVVM, Open Source, Silverlight, USCloud, Windows, Windows 8, WP7, WP8

Scaling Collaborative Applications

One of our local MVPs, Michael Perry, has written a great article about scaling collaborative Windows 8 applications with Correspondence and Windows Azure.

Azure is a great way to quickly deploy and scale your web sites. Correspondence is a rich framework for bringing collaborative experiences to multiple platforms. When these two come together, amazing things can happen.

http://qedcode.com/content/scaling-collaborative-applications-azure-and-correspondence

For those that don’t know, Correspondence is Michael’s innovative collaboration framework for occasionally connected smart clients and web applications. Correspondence is hosted on CodePlex at http://correspondence.codeplex.com/ and samples can be found on Michaels blog at http://qedcode.com.

Cloud, Development, Featured, MVVM, Windows, Windows 8

Windows 8 Games and Roaming Data

I was recently asked to write an article for our upcoming 30-to-Launch series about using RoaminData in a Windows 8 game. Here’s that article and a link to the code.

Every game is unique, and carries with it a unique set of game data to save and load at various points of the games lifecycle. In the past, most gamers – especially casual gamers – had only one device on which their favorite game was installed. Data storage for those games was simpler for developers to manage in that the game data could be saved locally in a variety of formats, and loaded when the game started or at the user’s request, and was all self-contained within the game itself. Today, with people owning multiple devices both at work and at home, game experiences are more challenging to manage as users want to be able to share game data between different computers without having to store that data on some external device like a thumb drive or portable hard drive. Although there are a variety of custom code solutions that could be developed to support the sharing of game data between computers, WinRT provides a set of classes that facilitates this type of data sharing automagically – it’s called the Windows 8 Roaming Data Store. In this article, we’ll look at a simple game implemented for WinRT that uses the Roaming Data Store that enables a player to stop gameplay on one machine and resume it on a second.

Enter the Game

For this article, we will be using a very basic WinRT game based on the popular game Bulls and Cows, often referred to as Mastermind, to illustrate how game data can be saved and shared using the different features of the Roaming Application Data Store in WinRT.

Figure 1 – Sample Mastermind Game

Gameplay is very straightforward – the computer draws a random set of 4 colored boxes from a set of 6 different color choices to form a “code”. The player, often referred to as the code breaker”, provides a series of “guesses” to the solution by selecting a combination of 4 colors via the large buttons on the bottom that the game engine will test against the solution. The player will receive one red indicator for each color the player selects that represents the proper color at the proper position in the solution, and one white indicator for each color the player selects that is part of the solution but NOT in the proper location. In the sample above, the player was able to solve the game in 7 tries using deductive reasoning based on the red and white indicators for each of their guesses. For our game, we want to create an environment where the user can save off their current game state, and restore it on a different computer at some time in the future. To understand how to achieve this, you first have to understand how the Roaming Application Data Store works on WinRT.

Roaming Application Data Store on WinRT

The Roaming Application Data Store is part of the larger WinRT Application Data Store that provides data synchronization between computers sharing a common application. The data is synchronized through the use of a shared cloud storage area attached to a user’s Microsoft account.

Figure 2 – Synchronizing Data via the Roaming Data settings

The Application Data Store is comprised of three separate data storage areas:

  • Local Settings – data that is stored and scoped locally to this single instance of an installed application
  • Roaming Settings – data that is shared between devices on which the user has installed a particular application
  • Temporary Settings – transient data created by the application, stored and scoped locally to a single machine, and could be deleted by the OS at any time

Each of these three data stores can be further broken down into App Files and App Settings.

App Settings

App Settings are stored in the registry, exposed to the developer as a set of simple Key/Value pairs into which any valid WinRT data type can be stored (if binary types are needed, the developer must use App Files instead of App Settings). App Settings support the concept of Containers, into which sets of related App Settings can be organized and stored together. A default container is used when none is explicitly specified, or developers can create their own containers up to 32 levels deep to better organize their application settings. Composite Settings can also be used to support atomic updates of related settings to ensure data consistency during concurrent access and roaming.

App Files

The Files interface gives the developer a way to store serialized objects, data files, or other complex objects using the familiar File patterns. Under the covers, App Files are stored on the file system in a hidden folder on the user’s computer, located beneath the application’s installation directory. Files can be listed, created, deleted and updated using the classes in the System.IO namespace.

Both App Settings and App Files are automatically synchronized between machines on which the application is installed. By simply writing to the App Settings or App Files within the Roaming Data store, data synchronization is automatic.

Using the Roaming Application Data Store in the game

NOTE: You can download the code sample that goes with this post from CodePlex at the following URL:

http://win8roamingstorage.codeplex.com/

The first step to incorporating roaming data was to get the game up and running with all the basic features and decide on what bits of state I needed to save. I wanted to make sure that I had something simple to serialize and deserialize from storage, and I also wanted to experiment with both App Settings and App Files to see which ones worked better for different situations.

Saving Game State

Since my game logic was stored in a separate set of classes from the application UI, and I had used the MVVM pattern for managing application state for data binding, I had everything I needed in one place – the ViewModel. I was tempted to just save off the entire MainViewModel itself – all in one chunk – but decided instead to save off pieces of it to save space (see Observations: Quota below). My MainViewModel does a lot more than just hold state, so I selected just the bits I needed to persist into roaming storage. So, after every move that was submitted by the player, I called out to the following method:

private async void SaveGameState()
{
	StorageHelper.SetGameInProgress();
	await StorageHelper.SaveObjectToRoamingFolder(STR_Gamejson, _game);
	await StorageHelper.SaveObjectToRoamingFolder(STR_Movesjson, Moves);
	StorageHelper.PutObjectToSetting<string>("MoveSlotOne", MoveSlotOne);
	StorageHelper.PutObjectToSetting<string>("MoveSlotTwo", MoveSlotTwo);
	StorageHelper.PutObjectToSetting<string>("MoveSlotThree", MoveSlotThree);
	StorageHelper.PutObjectToSetting<string>("MoveSlotFour", MoveSlotFour);
}

This method uses a helper class I created to save App Files and App Settings into the roaming data store.

First, we tackle saving a file to the Roaming Folder. I’ve got two examples in my source code for this – first is the Game object that tracks the current state of the game including the current solution, history of moves, number of moves remaining, etc. The second is the PlayerMoveViewModel objects stored in the Moves collection. These are wrappers around the GameMove objects that contain UI-friendly representations of the Move data as well as the corresponding MoveResults (i.e. # of white and red indicators). The method used here is SaveObjectToRoamingFolder on my StorageHelper class:

public async static void SaveObjectToRoamingFolder(string filename, object o)
{
	var appData = ApplicationData.Current;
	string jsonData = await JsonConvert.SerializeObjectAsync(o);
	StorageFile sampleFile = await appData.RoamingFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
	await FileIO.WriteTextAsync(sampleFile, jsonData);
}

I’m using Json.NET for my JSON serialization needs as I’ve used it before, it’s fast, and easy to install via NuGet

. By using JSON, I minimize the size of each stored file to approx. 1KB for both the Moves collection and the Game object itself.

Next we tackle the four buttons the player was using to enter their guesses. I still feel that storing these settings are not specifically required from a usability perspective, but I thought it would add a nice touch to the game to have the board look exactly as it had before the player left it on their previous machine. To store these four settings, I decided to use the App Settings data store to see how that would work out. I extended my helper class with the PutObjectToSetting<T>() method to make this easy:

public static void PutObjectToSetting<T>(string key, T value)
{
	var appData = ApplicationData.Current;
	appData.RoamingSettings.Values[key] = value;
}

Short and sweet, this method simply attaches to the current RoamingSettings object and inserts a value according to a specific key if none exists, or updates the value of that key if already present. I’ve recently learned that people are calling this an “upsert”, although I’m not sure how I feel about that term 🙂

Loading Game State

Saving the game state was really easy – after every move, the game would save off the current state of the board and the 4 input buttons to the Roaming Store. Retrieving the data was a bit more challenging as I had identified 3 use cases for loading data:

  • Restarting the game on the local machine
  • Restarting the game on the secondary machine
  • Updating the currently running game on the local machine with data from the secondary machine.

The first two use cases are the primary use cases I identified for this game. I wanted to make sure that I could effectually stop the game on the local machine and restore it back to where I came from on the remote machine. I also wanted to consider the situation where I might pause a game on one machine and pick it up on another, only to come back to the first machine later. This was a bit more work, but ultimately boiled down to some additional code at launch time, and an event to register for while the app was running.

MVVM is a great pattern for separating UI logic from Application logic, but sometimes – as in the case of initially launching the application, there can be some overlap. My sample application uses the MvvmLight Preview library from Laurent Bugnion at GalaSoft (also available via a convenient NuGet package) to make this easier to manage. When my application launches, I use the MvvmLight Messenger object to send a notification to the UI that the user needs to be asked if they want to load the existing game, or start a new one when saved game state is found. I didn’t want to do this in the UI, which would have simplified the code, as I felt it broke the MVVM pattern and I wanted to keep to the pattern as much as possible.

So, in the constructor for the MainViewModel object, I register a listener for the GameBoardReadyMessage to check for existing game state and alert the UI if necessary. Otherwise, we trigger the beginning of a new game and let the user start entering data.

Messenger.Default.Register<GameBoardReadyMessage>(this, (message) =>
{
	if (StorageHelper.GameInProgress)
	{
		var msg = new AskForGameRestoreMessage();
		Messenger.Default.Send<AskForGameRestoreMessage>(msg);
	}
	else
	{
		StartNewGame();
	}
});

When the Main Page launches, it send a GameBoardReadyMessage when it’s ready to be loaded, and registers to listen for AskForGameRestoreMessage messages to arrive from the MainViewModel. When AskForGameRestoreMessage is triggered, the code-behind in the MainPage will prompt the user to confirm that they want to load the existing game (LoadSavedGameMessage) or start a new one (StartNewGameMessage). Depending on the answer, additional messages are fired to alert the ViewModel of the user’s selection. The path we want to follow here is the LoadSavedGameMessage path in the MainViewModel, as implemented in the LoadSavedGame method:

private async void LoadSavedGame(ApplicationData appData)
{
	try
	{
		CurrentGame = await StorageHelper.GetObjectFromRoamingFolder<Game>(appData, STR_Gamejson);
		CurrentGame.OnFailure += _game_OnFailure;
		CurrentGame.OnVictory += _game_OnVictory;
		Moves.Clear();
		var moves = await StorageHelper.GetObjectFromRoamingFolder<ObservableCollection<PlayerMoveViewModel>&t;(appData, STR_Movesjson);

		foreach (var move in moves)
		{
			Moves.Add(move);
		}

		MoveSlotOne = StorageHelper.GetObjectFromSetting<string>(appData, "MoveSlotOne");
		MoveSlotTwo = StorageHelper.GetObjectFromSetting<string>(appData, "MoveSlotTwo");
		MoveSlotThree = StorageHelper.GetObjectFromSetting<string>(appData, "MoveSlotThree");
		MoveSlotFour = StorageHelper.GetObjectFromSetting<string>(appData, "MoveSlotFour");
	}
	catch (Exception ex)
	{
		// show error message
		ClearSavedGameState();
		Messenger.Default.Send<ErrorLoadingGameMessage>(new ErrorLoadingGameMessage(ex));
		// start new game
		StartNewGame();
	}
}

In this code sample, we’re attempting to pull out all of the saved game state from both App Files and App Settings and reconstitute the game in progress. If anything goes wrong, we let the user know via an alert and just start a new game. The methods I added to the StorageHelper class do the reverse of the work we did to save the object to storage, and instead pull the data back out:

public async static Task<T> GetObjectFromRoamingFolder<T>(ApplicationData appData, string filename)
{
	StorageFile sampleFile = await appData.RoamingFolder.GetFileAsync(filename);
	string jsonData = await FileIO.ReadTextAsync(sampleFile);
	var o = await JsonConvert.DeserializeObjectAsync<T>(jsonData);
	return o;
}

GetObjectFromRoamingFolder<T> takes the data from the Roaming Store and uses Json.NET to turn that data back into the object of our choice (note that this method has to be marked as async because the underlying access to the RoamingFolder requires await).

public static T GetObjectFromSetting<T>(ApplicationData appData, string setting)
{
	var raw = appData.RoamingSettings.Values[setting];
	T obj = (T)raw;
	return obj;
}

Lastly, the GetObjectFromSetting<T>() method pulls back a value from the RoamingSettings collection and casts it into the proper type before returning.

Other things to consider

There are a few specifics related to the Roaming Data store that need to be considered before using its capabilities in your application. I didn’t account for all of them in my sample, but I wanted to list the more important ones here for you to consider when implementing Roaming Data in your game:

Quotas

Unlike data stored in the Local Data area, Roaming Data is governed by a storage quota

, as defined by the RoamingStorageQuota property of the ApplicationData object. This quota provides a maximum size for data that can be synchronized in the cloud via the Roaming Data store. As of this writing, the current RoamingStoreQuota value is 100KB. If this limit is exceeded, the application will continue to run but the data will NOT be synchronized to the cloud for access by other installations. For game data, this is an important consideration as you design your game. You’ll need to optimize the amount of data that is stored, and the serialization formats used, to ensure that you stay within this limit or risk shutting down the automatic synchronization.

Versioning

Games, just like traditional applications, evolve over time to take on new features, fix bugs, and improve gameplay. You should consider a versioning strategy for your Roaming App data just like you’d consider a versioning strategy for the game itself. The ApplicationData class provides a Version property as well as a SetVersionAsync() method to allow you to set a version on your data, and check in when loading the application data. If the version number of the stored data is less than the version your application is expecting, the app can either reject the saved game state in favor of a new game, or you can provide an update strategy to convert the old saved game data to the new format. Current guidance is to use sequential and incrementing version numbers, starting at 1, for your Application and ApplicationData versioning needs.

DataChanged event

Depending on how your game is intended to be used, there might be a situation where there is more than one concurrently running instance of your game. In this situation, the data synchronized via the cloud could be different or even older, than the data you’re working with locally. This could create a data collision of sorts, where the application will need to make a decision on how to proceed. To aid you in dealing with these collisions, the Roaming Data store provides a simple event to which you can connect an event handler to deal with this situation – the DataChanged event:

public event TypedEventHandler<ApplicationData, Object> DataChanged

By subscribing to this event, your application will be notified when the game state on another computer has changed, and you can respond accordingly. In my sample application, I respond to this event by calling into LoadSavedGame, passing in the provided ApplicationData object to refresh the game state and the UI.

Please note: The DataChanged event is NOT intended to be used to facilitate player moves in a turn based game. Not only is the game data synchronized for a single Microsoft account, the rate at which the updates occurs is not guaranteed to be timely enough for acceptable game play. There are other techniques, such as Sockets, that provide a much better alternative to creating networked turn-based games and applications.

Summary

This was a really fun project for me to do. I had never written a game at all before, in any shape or form, so I was concerned about that aspect of it as much as the strategies I’d use for loading and storing game state. I’ve posted all my code on CodePlex at the following URL for you to download and inspect at your leisure:

http://win8roamingstorage.codeplex.com/

Please keep in mind that this is not a “complete” game, in that it is not something I’d consider ready for the Windows Store (at least not yet) but it will be fun to continue working on it to get there.

More detail about the Roaming Application Settings, and the ApplicationData object can be found all over the web. Here are a list of additional articles, references and code samples to help you get started.

Development, MVVM, Product Announcements, WP7

P&P Windows Phone Guidance Released

A couple of new Patterns & Practices guidance papers have been released for Windows Phone. I haven’t read them yet, but they look really interesting. Here are some links for your enjoyment:

 

Development, Events, MVVM, Oklahoma, School of Dev, Silverlight, Tulsa, Windows, WP7

Tulsa School of Dev

Mark your calendars – it's time for the annual Tulsa School of Dev community conference!

May 27, 2011 at 700 N Greenwood Ave in Tulsa, OK

[bingMap location=”700 N Greenwood Ave, Tulsa, OK 74106-0702″ zoom=”13″]

6 Tracks!

36 sessions!

Amazing speakers!

Tons of Prizes!

 

All it takes to get in is a donation of 2 cans of food for the Oklahoma Food bank – surely you have some extra canned goods lying around that you can bring with you?  You';ll get some great training on the latest mobile, .NET, SQL Server, SharePoint and Java technologies and help your fellow man along the way.

I will be there, speaking on Blend and WPF as well as discussing the latest in Windows Phone 7 (you've heard of Mango by now, haven't you?)

Come join us for a great time by registering today at http://tulsasod2011.eventbrite.com

Development, Featured, MVVM, Silverlight, WP7

Gestures in Windows Phone 7

A friend contacted me yesterday asking me how to enable some sort of side-to-side scrolling of images, similar to the way to that the Pictures Viewer works. He looked at taking a ListBox, turning it on its side and just scrolling sideways, but it didn’t give him the “feel” that he wanted.  I thought it would be a fun diversion from the other stuff I was doing to use this request as an excuse to start looking at the gesture support in WP7.

As it turns out, doing this was very easy, and only required the addition of 2 libraries – both from the XNA Framework for WP7.  I’ll use this blog post to document how I did it, and hopefully come back later and add some snazzy transitions and other stuff in the future.  I used my Netflix Browser application as the inspiration for this application, so if you’re familiar with what I did there the data access portion will make total sense.  I also used MVVM Light, which is my current favorite MVVM framework, although using MVVM is not necessary for this type of demonstration.

In this application, I have one main page that displays the BoxArt from the currently selected movie. As you swipe left and right, the application swaps out the images, in order, to create a “previous/next” type of effect.  I haven’t added any animations or anything yet – hopefully that will come in a future version. The magic here is all in the ViewModel and the Silverlight Manipulation Events – so lets dive in and take a look…

The ViewModel

We start off by creating a simple view model with two properties:

  • Items – this is a collection of the movies that we’re tracking. In my code I limit this to 20 movies just so things don’t take too long to load.
  • CurrentItem – this is the currently selected item from the Items collection that the UX will data bind to. As necessary, this item switches its source from one movie to the next, with the expectation that the UX will automatically update to reflect the newly selected movie.

I’m also tracking an internal variable, SelectedIndex, that will help us keep track of where the CurrentItem is in the list of Items.  We use logic to constrain this index to the bounds of the Items list so we don’t get any out-of-range or out-of-bounds types of exceptions.

Since the ViewModel is responsible for loading up our data, we need to add that next.  I’ve shown the new OData library before – this time, we’re also responding to the LoadCompleted event on our DataServiceCollection<T> so that we can initialize the SelectedIndex property and the CurrentItem property to correspond with the first item in the list.

private void LoadRuntimeData()
{
    Uri serviceUri = new Uri("http://odata.netflix.com/catalog", UriKind.Absolute);
    NetflixCatalog catalog = new NetflixCatalog(serviceUri);

    Uri queryUri = new Uri("/Titles?$filter=Rating eq 'PG' and ReleaseYear eq 1988&$orderby=AverageRating desc&$top=20", UriKind.Relative);

    _items = new DataServiceCollection<Title>(catalog);
    _items.LoadCompleted += new EventHandler<LoadCompletedEventArgs>(_items_LoadCompleted);
    _items.LoadAsync(queryUri);
}

private void _items_LoadCompleted(object sender, LoadCompletedEventArgs e)
{
    this.SelectedIndex = 0;
    this.CurrentItem = this.Items[this.SelectedIndex];
}

Once the data is loaded, the method that does the heavy lifting here is called ChangeSelectedIndex and takes an integer (+1 or –1) as a parameter.

internal void ChangeSelectedIndex(int modifier)
{
    // validate input
    var selectedIndex = this.SelectedIndex;
    if (selectedIndex + modifier < 0)
        return;
    if (selectedIndex + modifier >= this.Items.Count)
        return;

    // change the index and reset the current item
    this.SelectedIndex += modifier;
    this.CurrentItem = this.Items[this.SelectedIndex];
}

This parameter is used to track the direction of movement within the Items collection and ultimately determines which item needs to be displayed. We do some bounds checking to make sure that we’re staying within the range of the Items collection, but other than that we use it just to find the correct item and set it to the CurrentItem property.

How does this method get called?  We use the MVVM Light Messaging infrastructure to make that happen.  In the ViewModel constructor, I add one line of code to listen for the right message:

Messenger.Default.Register<SelectionChangedMessage>(
    this, (message) => ChangeSelectedIndex(message.Modifier));

At this point, everything is wired up and we're ready to move on to the UX

The User Experience

Once the ViewModel is created, we need to build the UX.  This time, instead of a ListBox to display all the downloaded movies, we’re using only an Image control that’s been configured to respond to user gestures. In Silverlight for WP7, we do that through 3 different event handlers:

  • ManipulationStarted – user is initiating a gesture (pan, flick, etc)
  • ManipulationDelta – user gesture is “in progress”
  • ManipulationCompleted – user has completed gesture (removed fingers, etc)

Each of them are valuable in their own right, but for our purposes, we only want to track the times that a user completes a gesture so that we can respond to it.  To make sure that I captured the gesture from anywhere on the page, I added an event handler to the PhoneApplicationPage object (the root of our XAML document). 

For the next part, Silverlight itself does not contain all the framework bits to do what we want it to.  For additional help, we’re going to bring in 2 of the XNA libraries.  For those of you playing along at home, you’ll need to add 2 references:

  • Microsoft.Xna.Framework
  • Microsoft.Xna.Framework.Input.Touch

These libraries serve to extend our gesture-handling capabilities allowing us to capture all the data related to these gestures and use them in our applications.  Without these references included, we’d get compile errors saying that certain types we were trying to access were not defined in the project, and suggest that we were missing some project references.

Now that the references are in place, we can finish configuring our gesture listener.  Inside the codebehind for the page, we do a little bit of testing to make sure we are tracking the right kind of gesture, and send the processing on to the Messaging infrastructure.

private void Image_ManipulationCompleted(object sender, System.Windows.Input.ManipulationCompletedEventArgs e)
{
    while (TouchPanel.IsGestureAvailable)
    {
        // Read and respond to the current gesture
        GestureSample gesture = TouchPanel.ReadGesture();

        if (gesture.GestureType == GestureType.Flick)
        {
            // determine direction
            var modifier = gesture.Delta.X > 0 ? -1 : 1;

            // send message to ViewModel
            Messenger.Default.Send<SelectionChangedMessage>(new SelectionChangedMessage(modifier));
        }
    }
}

In this code, we first check to make sure that we’re actually responding to a real gesture using the IsGestureAvailable property of the TouchPanel object (yep – this is one of those XNA objects I was telling you about).  To limit the scope of what gestures we want to work with, we can also add the following line to the constructor to tell the TouchPanel that we’re only interested in Flick gestures:

TouchPanel.EnabledGestures = GestureType.Flick;

Once we’ve determined that we’re working with a Flick gesture, we have to figure out whether the user was flicking to the left, intending to go to the next picture, or flicking to the right, intending to go back.  Luckily for us, that’s really easy to do with the GestureSample class’s Delta property.  The delta we want is along the X axis, tracking left to right or right to left movement.  If  the GestureSample.Delta.X value is positive, that means the user flicked from left to right, indicating that they wanted to move back in the picture stack. If the GestureSample.Delta.X value is negative, the user flicked from right to left and wants to go to the next picture (I know, this sounds upside down, but really – it does work).

When we have the direction the user wanted to go, we can set the index modifier to either +1 (next picture) or –1 (previous picture) and send it to the VM.  We do this through the Messaging infrastructure provided by MVVM.  I created a simple class called SelectionChangedMessage that has only one int property, Modifier, to express that value.  Once dumped into the message bus, the ViewModel will pick it up, run the code we wrote earlier, and switch out the current picture with the next one.  Magic!

At this point you might be saying to yourself "gosh Chris, I thought with MVVM we weren't supposed to have any code in our codebehind files?” To that I say "nay, nay". Code in the codebehind is perfectly acceptable so long as what you're doing relates to the UX itself. If you're manipulating business objects, or doing something related to business or data access logic, then you definitely need to work in the VM.

Summary

Adding gesture support to your WP7 application is really easy – it’s a bit trickier to make some nice looking transitions between elements, or within gestures. I hope to add to this post later with some tips on how you can do that. For now, you can download the code from this post using the link below.

Development, MVVM, Product Announcements, Silverlight, WP7

Prism 4.0 Released!

Gg406140.pnp-logo(en-us,PandP.10).pngPrism provides guidance designed to help you more easily design and build rich, flexible, and easy to maintain Windows Presentation Foundation (WPF) desktop applications, Silverlight Rich Internet Applications (RIAs) and Windows Phone 7 applications. Using design patterns that embody important architectural design principles, such as separation of concerns and loose coupling, Prism helps you to design and build applications using loosely coupled components that can evolve independently but which can be easily and seamlessly integrated into the overall application. Such applications are known as often referred to as composite applications.

Links

Audience

Prism is intended for software developers building WPF or Silverlight applications that typically feature multiple screens, rich user interaction and data visualization, and that embody significant presentation and business logic. These applications typically interact with a number of back-end systems and services and, using a layered architecture, may be physically deployed across multiple tiers. It is expected that the application will evolve significantly over its lifetime in response to new requirements and business opportunities. In short, these applications are “built to last” and “built for change.” Applications that do not demand these characteristics may not benefit from using Prism.

Key Benefits

  • Provides guidance and a re-usable library to help you develop flexible, easy to maintain WPF and Silverlight composite applications
  • Helps you to understand, implement and use key design patterns, such as MVVM and Dependency Injection
  • Supports the development of modular applications, allowing parts of your application to be fully developed and tested by separate teams
  • Helps you re-use application code and components across WPF and Silverlight, allowing you to create multi-targeted client experiences
  • Allows you to build a designer-friendly, dynamically composed user interface for your application
  • Includes reference implementations, quick-starts, hands-on-labs, as well as a comprehensive developers guide to get you up to speed quickly
  • Includes full source code to support code re-use or customization or for reference and education

In this Release

  • Prism Library for WPF, Silverlight and Windows Phone 7
  • Signed binary assemblies
  • Full source code
  • Example Applications and Hands-on-Lab Source Code
  • Reference Implementations (2)
  • QuickStarts (12)
  • Hands on Labs (2)
  • Documentation
  • Comprehensive developers guide showing how to use Prism within your application
  • A printable PDF of the developers guide – available on CodePlex
Development, Featured, MVVM, Product Announcements, Silverlight, WP7

OData v2 and Windows Phone 7

panoramaYesterday at PDC10, Scott Guthrie demonstrated a Windows Phone 7 application that he was building using Silverlight.  During this time, he mentioned that a new OData stack had been released for .NET which included an update to the library for Windows Phone 7. Now you might think that this was just a regular old upgrade – you know… bug fixes, optimizations, etc.  It was, but it also signaled a rewrite of the existing CTP that had been available for Windows Phone 7.  In this rewrite, there are some important feature changes that you need to be aware of, as announced by Mike Flasko on the WCF Data Services Team Blog yesterday:

LINQ support in the client library has been removed as the core support is not yet available on the phone platform.  That said, we are actively working to enable this in a future release.  Given this, the way to formulate queries is via URIs. We’ve added a LoadAsync(Uri) method to the DataServiceCollection class to make it simple to query services via URI. So you can easily support the phone application model we’ve added a new standalone type ‘DataServiceState’ which makes it simple to tombstone DataServiceContext and DataServiceCollection instances

In this post, I’ll go through the first 2 of the changes explain what they mean to you, and show you how to adapt your application to use the new library.  In a future post, I’ll explore the new support for the phone application model and tombstoning.

Where are the new bits?

Firs things first – we need to get our hands on the new bits.  There are 3 new download packages available from the CodePlex site for OData:

  • OData for .NET 4.0, Silverlight 4 and Windows Phone 7 (Source Code, if you need it)
  • OData Client Libraries and Code Generation Tool (just the binaries, and a new DataSvcUtil tool)
  • OData Client Sample for Windows Phone 7 (great for learning)

After downloading, don’t forget to “unblock” the ZIP files, or Visual Studio will grouch at you.  Just right-click on the ZIP file and choose Properties from the menu.  If there is a button at the bottom labeled “Unblock”, click it.  That’s it. Once you get the Client Libraries and Code Generation Tool zip file unblocked, and unzipped, replace the assembly reference in your project from the old CTP version of the System.Data.Services.Client.dll to the new version supplied in this new download. You’ll also need to re-generate the client proxy in your code using the new version of DataSvcUtil.  Remember how?  Just run this command from a Command Prompt opened to the folder where you unzipped the tools DataSvcUtil /uri:http://odata.netflix.com/catalog /dataservicecollection /version:2.0 /out:NetflixCatalog.cs Note: You must include the /dataservicecollection attribute (which itself requires the /version:2.0 attribute) to get INotifyPropertyChanged attached to each of your generated entities.  If you’re not going to use the DataServiceCollection objects as I will, then you might not need this, but I’m using it in my samples if you’re following along at home. Now you can replace your old proxy classes with these new ones.  Now is when the real fun begins…

Wherefore art thou LINQ?

The most impactful change has got to be the removal of LINQ support by the DataServiceProvider.  From Mike’s post:

LINQ support in the client library has been removed as the core support is not yet available on the phone platform.  That said, we are actively working to enable this in a future release.  Given this, the way to formulate queries is via URIs.

Wow.  I don’t know about you, but I have come to depend on LINQ for almost everything I do in .NET anymore, and this one really hits me square between the eyes. Fortunately, these URI-based queries aren’t too complicated to create, and Mike also points out that they’ve added a new method on the context to make this a bit easier on us:

We’ve added a LoadAsync(Uri) method to the DataServiceCollection class to make it simple to query services via URI.

With my custom URI and this new method, it’s actually almost as simple as before, sans LINQ doing all my heavy lifting.

Surgery time

So – to finish upgrading my Netflix application, I’ve got to make some changes to the existing MainViewModel.LoadRuntimeData method.  Here’s what it looks like from the last implementation:

private void LoadRuntimeData()
{
    Uri serviceUri = new Uri("http://odata.netflix.com/catalog", UriKind.Absolute);
    NetflixCatalog _catalog = new NetflixCatalog(serviceUri);
    var query = _catalog.Titles
        .Where(t => t.Rating == "PG" && ReleaseYear = 1983)
        .OrderByDescending(t => t.AverageRating)
        .Take(20);
    var dsq = query as DataServiceQuery<Title>;
    dsq.BeginExecute(
        (callback) =>
        {
            var results = dsq.EndExecute(callback);
            DispatcherHelper.CheckBeginInvokeOnUI(() =>
            {
                Items.Clear();
                foreach (var item in results)
                {
                    Items.Add(item);
                }
            });
        }, null);
}

As you can see, this contains quite a bit of LINQ magic. Unfortunately, that's going to have to go. The only thing we can really salvage, is the instantiation of the NetflixCatalog class based on the Uri to the main OData service endpoint.  This is important – we don’t use a URI with all the query string parameters in one shot because the DataContext class needs to have a reference to the base URI for the service, and future queries will be based on that base URI.

Rebuild the query

Now that we have a reference to the main service, we now have to build our own query. To do this, we’ll need to manually convert the LINQ query into something that the previous DataContext would have done for us.  There are a couple ways to figure this out. First, we could dive into the OData URI Conventions page on the OData web site and read all about how to use the various $ parameters on the URL string to get the results we want.  The sneaky way, however, would be to run the old code with the old provider and look at the URI that got sent to the Netflix service by snooping on it with Fiddler.   The results are the same – one long URL that has all the parameters included.

http://odata.netflix.com/Catalog/Titles?$filter=Rating eq 'PG' and ReleaseYear eq 1983&$orderby=AverageRating desc&$top=20

Although it's pretty long, note how clean the URL is – Where becomes $filter, OrderBy becomes $orderby and Take becomes $top. This is what is so great about OData: clean, clear, easy to read URLs. Armed with our new URI, we can go in and replace the LINQ query with a new Uri declaration. Since we already have the new DataContext based on the service’s URI, we can remove that from here and just use the stuff that comes after:

/Titles?$filter=Rating eq 'PG' and ReleaseYear eq 1983&$orderby=AverageRating desc&$top=20

Don’t forget to mark this new URI as UriKind.Relative.  This new URI is definitely NOT an absolute URI, and you’ll get an error if you forget. Here’s what the new code looks like so far:

Uri serviceUri = new Uri("http://odata.netflix.com/catalog", UriKind.Absolute);
NetflixCatalog catalog = new NetflixCatalog(serviceUri);

Uri queryUri = new Uri("/Titles?$filter=Rating eq 'PG' and ReleaseYear eq 1983&$orderby=AverageRating desc", UriKind.Relative);

ObservableCollection –> DataServiceCollection

Now that the DataContext is created, and the replacement query is built, it's time to load up the data. But what are we going to load it up into? Depending on which version of my old application you were using, you might see code like I listed above with ObservableCollection or you might have the version that I converted to use the DataServiceCollection.  This new model definitely wants us to use DataServiceCollection as it has some neat ways to manage loading data for us.  That means we will have to swap out our definition of the Items property with a DataServiceCollection. First, replace instances of ObservableCollection with DataServiceCollection.  Second, remove the initializer for the Items property variable – it’s no longer needed. Third, and this is optional, you can tap into the Paging aspects of the DataServiceCollection by adding a handler to the DataServiceCollection.Loaded event. Note: I don’t need this feature now, so I’m not going to add code for it.  I’ll leave it as an exercise for the reader,or you can hang on for a future post where I add this back in.

Run the query

Now that my query URIs are defined, and my DataServiceCollection objects are in place, it’s time to wire up the final changes to the new query.  For this, all I have to do is initialize the Items property with a DataServiceCollection and ask it to go run the query for us.

_items = new DataServiceCollection<Title>(catalog);
_items.LoadAsync(queryUri);

Notice the simplified version of the loading process.  Instead of having to go through and manually load up all the items in the ObservableCollection, here the DataServiceQuery handles all that hard work for us.  The main thing we need to remember is to initialize it with the DataContext before calling out to it.

Wrapping it all up

Now that we’ve got everything working, let’s take a look at the whole LoadRuntimeData method:

private void LoadRuntimeData()
{
    Uri serviceUri = new Uri("http://odata.netflix.com/catalog", UriKind.Absolute);
    NetflixCatalog catalog = new NetflixCatalog(serviceUri);

    Uri queryUri = new Uri("/Titles?$filter=Rating eq 'PG' and ReleaseYear eq 1983&$orderby=AverageRating desc&$top=20", UriKind.Relative);

    _items = new DataServiceCollection<Title>(catalog);
    _items.LoadAsync(queryUri);
}

Except for a few minor changes to the ViewModel properties (all we really did was change a type from ObservableCollection to DataServiceQuery) the actual code changes were pretty minimal. I still don’t like that I have to write my own URL string, but the team is going to address that for me in the future, so I guess I can hang on until then. I’ve uploaded the project to my Skydrive, so you can download this version to see it in action.  It’s still not a very exciting application, but it does show off how to use the new OData library.  As always, thanks for reading, I hope you found it valuable, and let me know if you have any questions.

Development, MVVM, Silverlight, WP7

Update to my Sample WP7 Application

Last night, I spoke at the Dallas XAML User Group and did a very interactive session on building WP7 applications using MVVM Light. After the talk, one of my favorite MVPs, Shawn Weisfeld, came up to me and told me that he was building a Silverlight application for one of his relatives who owns a bagel business in NYC (yum). In his work, he was using the DataServiceQuery<T> class to query OData data sources, but instead of using ObservableCollection<T> directly, he was using the DataServiceCollection<T>. I had not noticed this collection before, but using it seems to really clean up the code necessary to run these queries from Silverlight and WP7. Here’s a sample of what I mean – given that I have an INPC property called Items:

// Items is an ObservableCollection<Title>
NetflixCatalog catalog = new NetflixCatalog(new Uri("http://odata.netflix.com/Catalog"));

var query = catalog.Titles
    .Where(t => t.Rating == "PG" && t.ReleaseYear == 1983)
    .OrderByDescending(t => t.AverageRating)
    .Take(25);

var dsq = query as DataServiceQuery<Title%gt;;
dsq.BeginExecute((a) =>
{
    var results = dsq.EndExecute(a);
    DispatcherHelper.CheckBeginInvokeOnUI(() =>
    {
        Items.Clear();
        foreach (var item in results)
        {
            Items.Add(item);
        }
    });
}, null);

In my original code, I had several steps – create the query, cast as DataServiceQuery<T> and call BeginExecute.  After returning from that call, I had to retrieve the results and rip through them loading the Items collection.  If I was using a DTO, this would make more sense, but since it was just copying over the original items from the collection, this seemed like a bit of extra work.  I also had to deal with the issue of context switching between the UI thread and the background thread.  Not a huge effort, thanks to MVVM Light, but why write code you don’t need?

Thanks to Shawn’s input, I can now reduce this code to the following:

NetflixCatalog catalog = new NetflixCatalog(new Uri("http://odata.netflix.com/Catalog"));

var query = catalog.Titles
    .Where(t => t.Rating == "PG" && t.ReleaseYear == 1983)
    .OrderByDescending(t => t.AverageRating)
    .Take(25);

Items.LoadCompleted += new EventHandler(Items_LoadCompleted);
Items.LoadAsync(query);

In the LoadCompleted handler, the LoadCompletedEventArgs object gives me the hooks to process continuations as necessary  – overall this is much cleaner and much simpler code.

So far, I haven’t seen any downsides to using this approach, other than the fact that we’re now tying our Items property directly to OData rather than the more generic ObservableCollection<T>, but I bet this won’t be  problem for most instances. Besides, a DataServiceCollection<T> *is* an ObservableCollection<T>, so refactoring won’t be too much work if I do need to do it.

Thanks Shawn – great advice!

Note – I’m not reposting the code yet, but look for some additional details on a screencast that is in the works to go along with building this simple application.  I’ve gotten feedback and almost every presentation of this talk that I need to do a screencast version, so you guys will get what you’ve asked for!

Development, MVVM, Silverlight, WP7

My “Hello World” Windows Phone 7 Application

This entry is part 8 of 8 in the series Windows Phone 7

I’ve done a TON of Windows Phone 7 demos over the past few months, and I get asked all the time for access to download my samples. I’ve been meaning to post this application since I started all of this, but just never got around to it.  SO – here it is… the now Infamous MVVMLight-ified Netflix Catalog Sample!

imageimage

 

This is by no means a comprehensive sample, but it does show some of the neat features of WP7 as well as a sample for how to integrate MVVM Light into your phone applications.  Get the code from my Skydrive: