Archive

Posts Tagged ‘StackAttack’

Cancelling Periodic Updates

August 15, 2012 Leave a comment

“What are periodic updates” you might ask? Well, you probably know that you can update live tiles in code, from background services and using Push Notification Services. But sometimes, none of these are the right approach.

For a shipping company, Push Notification Services makes sense because each package is tied to a particular user. But a company that offers flight information might have hundreds of users, all with multiple devices, interested in the status of the same flight. For a flight app, push doesn’t make much sense. Especially when you consider that a large number of devices might be turned off when the server tries to deliver the information! Weather applications face the same problem: lots of users interested in the exact same data wanting updates at the same time.

What these companies need is an easy way to publish a live tile to a “central” area, then let devices update after an amount of time has passed or whenever the device wakes up. That’s what periodic updates do.

You can start a periodic update by calling TileUpdater.StartPeriodicUpdate. This method takes a Uri and a recurrence (HalfHour, Hour, etc.) You can also pass a DateTime to start updating if you don’t want to start immediately. When the time elapses (or the device wakes up and the time has already elapsed), Windows will automatically connect and download the Uri. What Windows expects to receive is an XML document that matches the Tile schema.

To stop periodic updates from code, simply call TileUpdater.StopPeriodicUpdate. But wait, Windows performs these updates automatically without the app actually running. What if the user never launches the app? For a weather application that’s perfectly alright, but for a flight tracker the data isn’t really useful after the flight has landed. It doesn’t make sense to pay for bandwidth (or battery) when the data won’t change again.

What we need is the ability for the server to tell Windows to stop polling for updates. Unfortunately there’s no option for that in the tile schema, but it is possible to cancel the subscription by setting an HTTP header in the response. From this answer on Stack Overflow:

The endpoint that you specify for the periodic notification needs to serve the XML content and set the X-WNS-Expires header (and perhaps X-WNS-Tag). If, for example, you’re using Windows Azure blob storage or Amazon S3 to host the template XML and sending that URI to startPeriodicUpdate, then you don’t have the opportunity to set those headers. You’ll need to set up a lightweight service that passes through the XML content and sets the headers appropriately.

[…] That URI will be checked until you call stopPeriodicUpdate; see Periodic Notification Overview:

Polling continues until you explicitly stop it or your app is uninstalled. Otherwise, Windows will continue to poll for updates to your tile or badge even if your app is never launched again.

Lastly, the Guidelines and checklist for periodic notifications does recommend:

Call the StartPeriodicUpdate or StartPeriodicUpdateBatch method each time your app is launched or brought into focus. This ensures that the tile content will be updated each time the user launches or switches to the app.

So there you have it.

Categories: Development Tags: ,

Filtering and Grouping ListView and GridView on Windows 8

August 1, 2012 4 comments

One of the questions I recently answered on Stack Overflow was how to filter and group data in ListView and GridView.

Filtering and grouping has traditionally be done with CollectionViewSource. Unfortunately,CollectionViewSource no longer has the Filter event or the GroupDescriptions property. It may seem like filtering and grouping are unsupported, but both can still be achieved using LINQ.

In your Xaml, add a CollectionViewSource in the Resources section of your page. Make sure IsSourceGrouped is set to true:

<common:LayoutAwarePage.Resources>

    <!–
        Collection of grouped items displayed by this page, bound to a subset
        of the complete item list because items in groups cannot be virtualized
    –>
    <CollectionViewSource x:Name="GroupsCV" Source="{Binding Groups}" IsSourceGrouped="True" />
    
</common:LayoutAwarePage.Resources>

 

Now, the CollectionViewSource (GroupsCV) should be set as the ItemsSource for your GridView:

<GridView ItemsSource="{Binding Source={StaticResource GroupsCV}}" />

 

Notice that CollectionViewSource is bound to a property called Groups. This property is part of my ViewModel. The value returned by the Groups property will be the result of a LINQ query. This confused me at first because I didn’t know what type the property should return. I settled on an enumerable grouping of comparable items. This pretty much works with any LINQ query of any type.

So, in your ViewModel (or whatever your DataContext is) add the following property:

private IEnumerable<IGrouping<IComparable, TItem>> groups;
public IEnumerable<IGrouping<IComparable, TItem>> Groups
{
    get { return groups; }
    set { SetProperty(ref groups, value); }
}

 

Now, whenever you want to change the grouping or the filter, just set the Groups property equal to a LINQ query like so:

Groups = from i in musicItems
         group i.Genre into g
         orderby g.Key
         select g;

 

LINQ does great with property expressions in queries at compile time, but what about letting the user pick from a list of property names and dynamically grouping by a property at runtime? Well, the only requirement for LINQ to be able to create a group is that whatever you pass it must implement IComparable.

Here’s a little extension method that takes the name of a property as a string and returns an IComparable:

static public class DataExtensions
{
    static public IComparable GetComparableValue<T>(this T item, string propName) where T : class
    {
        return (IComparable)typeof(T).GetTypeInfo().GetDeclaredProperty(propName).GetValue(item, null);
    }
}

With that in place, you can do a dynamic query by property name like this:

string groupByPropertyName = "Artist";

Groups = from i in musicItems
         group i by i.GetComparableValue(groupByPropertyName) into g
         orderby g.Key
         select g;

 

The examples above show how to create groups, but you can easily filter as well. On the 2nd line of the query (the line after the from) add a where clause. You can filter on any property and should even be able to use the GetComparableValue trick to dynamically filter on a property by quoted string name.

Original Question on Stack Overflow

Categories: Development Tags: ,

StackAttack

August 1, 2012 Leave a comment

I’ve been spending quite a bit of time on Stack Overflow trying to help developers by answering questions about Windows 8. Some of the questions have been really interesting and they’ve forced me to dig into areas of the platform that I haven’t spent a lot of time with yet. Whenever I find a question with an unusual or insightful answer, I’ll post the info on my blog and tag it StackAttack. Why StackAttack? Because I thought it sounded funny. It reminds me of those awesome Mac Attack commercials from the 80’s.

Categories: Development Tags: