in Software Development

How to disable item selection in the WinRT GridView

When I sat down to convert One Love to Windows 8.1 I decided to rework the way in which I present the selection of social networks when a user adds a new account.  In the free version you can add a single personal profile each for Facebook, Twitter and LinkedIn.  If you wanted to add LinkedIn Groups for example you would have to upgrade to the Professional version (which is an in-app purchase).  In the old version of One Love I would however not even present the availability of accounts which are not available in the free version.  In the new version I wanted to display to the user that these accounts are available, but the user must not be able to select them.  I also wanted to present them with some sort of indication that says “hey, you can add me but upgrade to the Pro version first”, as is depicted in the screenshot below.

Untitled8

So how would you go about doing this?  Remember from my previous blog post I discussed 3 ways in which you can handle data templates in the XAML GridView.  Under the section on data template selectors, I mentioned in passing that you can also access the container for a data item which allows you to disable the container which effectively disables selection for that item.

So, let us run step by step through the process of creating something similar to what I have done in the screenshot above.

Create the Data Templates

Seeing as I am using a DataTemplateSelector, am going to create 2 data templates.  One for the available state, and one for the unavailable state

The first data template called AccountSelectionListViewItemTemplate specifies the layout of the item which is available for selection and displays the image, name and service type. The second data template named AccountSelectionListViewItemTemplateUnavailable is used for items which are not available for selection.  Instead on repeating the entire layout from the first data template, I reuse the first template by creating a ContentControl with the ContentTemplate property specified as the first template, and then overlay all of that with the store logo and purchase message on a semi transparent dark background so that a little bit of the underlying account details displays through.

Create the DataTemplateSelector

Now that the two data templates are done, we need to create a DataTemplateSelector which will supply the correct data template at runtime.

All the data template does is to check if the account is locked, and if so it returns the template for a unavailable item, otherwise it returns the data template for an available item.  It also sets the IsEnabled propery of the item container to false for accounts which are locked so that they cannot be selected.

The SelectTemplateCore() method which I override receives 2 parameters.  The first parameter contains data for the GridView item, in my case an Account object.  The second parameter contains the container of the item – in the case of a GridView it is a GridViewItem.  (I casted it to a SelectorItem which is the base class of GridViewItem, but you can cast it to a GridViewItem all the same).  The GridViewItem/SelectorItem contains a property IsEnabled which allows you to disable the selection of the item.

Next up we create a XAML resource for the data template selector:

And finally we specify it as the DataTemplateSelector property of the grid view:

This produce the following output:

Untitled9

Changing the item container

One problem which may not be immediately apparent is that the opacity of the entire item container is lowered for items which are disabled.  This may or may not be a problem for you.  In my case I did not like that behaviour as I already overlayed disabled items with the store logo and purchase message and I did not want to opacity of the item lowered as well.  Luckily the solution is quite straightforward and all we need to do is change the item container style and set the DisabledOpacity property to 1, so that he opacity of disabled items is not altered:

And specify this new style as the ItemContainerStyle of the grid view:

This produces the following output:

Untitled10

What about the ListView?

This blog post demonstrated how to get the required behaviour with a WinRT GridView, but you can follow the same process for a WinRT ListView.

Source Code

As always the source code for this blog post is available on Github at https://github.com/beabigrockstar/DisableWinRTGridViewItem/