After a small tweak in

After a small tweak in css/scenario1.css—changing the simpleHeaderItem class height to 65px to make a little more room—the list will now appears as follows: Finally, back to WinJS.Binding.List.createGrouped, the third (and optional) function here is a group sorter function, which is called to sort the group data collection and therefore the order in which those groups appear in the ListView. 33 This function receives two group keys and returns zero if they’re equal, a negative number if the first key sorts before the second, and a positive if the second sorts before the first. The compareGroups function in the sample does an alphabetical sort, which I’ve updated in the modified version to again use world-ready sort ordering: function compareGroups(left, right) { return groupCompareGlobalized(left, right); } function groupCompareGlobalized(left, right) { var charLeft = cg.lookup(left); var charRight = cg.lookup(right); // If both are under the same grouping character, treat as equal if (charLeft.localeCompare(charRight) == 0) { return 0; } } // In different groups, we must rely on locale-sensitive sort order of items since the names // of the groups don't sort the same as the groups themselves for some locales. return left.localeCompare(right); For a two-level sort, first by the descending item count and then by the first character, we could write the following (this is in the modified sample; refer to this in the call to myList.createGrouped to see it in action): function compareGroups2(left, right) { var leftLen = filteredLengthFromKey(left); var rightLen = filteredLengthFromKey(right); if (leftLen != rightLen) { return rightLen - leftLen; } 33 This is entirely separate from creating a sorted projection of the items, for which you’d use WinJS.Binding.List.createSorted. 190

} return groupCompareGlobalized(left, right); function filteredLengthFromKey(key) { var filteredList = myList.createFiltered(function (item) { return key == getGroupKey(item); }); } return filteredList.length; Debugging Your Grouping Functions If your various grouping functions don’t seem to be working right, you can set breakpoints and step through the code a few times, but this becomes tedious as the functions are called many, many times for even modest collections. Instead, try using console.log to emit the parameters sent to those functions and/or your return values, allowing you to review the overall results much more quickly. To see what’s coming into the group sorting function, for example, try this code: console.log("Comparing left = " + left + " to right = " + right); ListView in the Grid App Project Template Now that we’ve covered the details of the ListView control and in-memory data sources, we can finally understand the rest of the Grid App project template in Visual Studio and Blend. As we covered in the ”The Navigation Process and Navigation Styles” section of Chapter 3, “App Anatomy and Page Navigation,” this project template provides an app structure built around page navigation: the home page (pages/groupedItems) displays a collection of sample data (see js/data.js) in a ListView control, where each item’s presentation is described by a WinJS.Binding.Template as are the group headings. Figure 5-4 shows the layout of the home page and identifies the relevant ListView elements. As we also discussed before, tapping an item navigates to the pages/itemDetail page and tapping a heading navigates to the pages/groupDetail page, and now we can see how that all works with the ListView control. The ListView in Figure 5-4 occupies the lower portion of the app’s contents. Because it can pan horizontally, it actually extends all the way across; various CSS margins are used to align the first items with the layout silhouette while allowing them to bleed to the left when the ListView is panned. 191