Update to my Sample WP7 Application
Posted on September 8, 2010 by Chris Koenig
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!
-
Anonymous
-
Anonymous





