Welcome to The Digital Lifestyle and Media Center Show Sign in | Join | Help
in Search
mControl for Windows Media Center

The Digital Lifestyle Developer Blog

Windows Media Center development hints, tips, tutorials and information

Working With Large Scrollers

This is a reasonably advanced topic, but since I've only just discovered the solution for it, I decided I may as well post it here so people who need the solution can use it.

Large scrollers can sometimes be a problem when you need to do large 'jumps' within them. The best example of this is the 'type-to-search' functionality that you find in the Music menu of Media Center. When you start to type the name of the album, artist etc. with either your keyboard or remote control, you will find that the selection jumps straight to the nearest matching item.

To replicate this in your own application can be troublesome.

Normally, Media Center only has two functions to use to control user navigation. The first is Input.NavigateInto. As we have seen before, every object has an 'Input' class associated with it. 'NavigateInto' requests that the current selection be changed to the object that you are Invoking the command on.

For example, if you had a button, putting the following command inside the UI for the button would result on it getting focus.

   <Invoke Target="[Input.NavigateInto]"/>

For collections though, this isn't all that useful. If you wanted to select a particular item in a scroller, you'd need to put in some complex rules inside the item that check not only that you WANT the focus to change, but also compare the index of the item against the index that is being searched for. It's possible - but it's slightly ugly.

There's an easier function though. The Repeater item has a special function called NavigateIntoIndex (see http://msdn2.microsoft.com/en-us/library/bb189530.aspx ). This is a very similar function to NavigateInto, but this time allows you to pass an index number. The repeater will then set the focus to the appropriate index element.

 

NOTE: Be careful when setting up complex events with these particular functions. Unlike a Windows session, when navigation events like clicks and focus changes are all queued up, Media Center does not queue navigation events. So if you try to fire off two or more NavigateInto or NavigateIntoIndex calls at once, one or more of them may be 'lost'.

To work around this problem, use Timers to offset the calls to NavigateInto. For example, make the first one happen immediately and then make the others happen at 1/10th of a second intervals - or whatever works well for you.

 

There's one major drawback with NavigateIntoIndex and NavigateInto though. Scrollers and repeaters work together to optimise the objects on screen. Part of this optimisation is only creating the actual repeated item when it becomes nessicary to create it. So for example, if you have 100 items in your list but never scroll past the 10th item, the 100th item will never actually be created as an MCML object.

So let's say you were in your own version of the Music section, you were exploring 'Ace of Base' and decided that you wanted to look for 'ZZ Top'. If you had 100 different artists, but only 12 were on the screen, calling NavigateIntoIndex with a parameter of '100' simply wouldn't work, because as yet, the 100th index does not actually exist.

You can tweak the repeaters 'Prefetch' attribute - which chooses how many item the repeater 'pre-loads', but then you are enforcing a strict maximum possible length of your search, which not only means you are just delaying the problem, but pre-loading hundreds or even thousands of entries isn't just time consuming, it can crash your Media Center application.

 

So what's the trick? Well, it's not too difficult, it's just got some kinda sketchy documentation.

Each scroller has a ScrollingData attached. If you check out the documentation - http://msdn2.microsoft.com/en-us/library/bb189586.aspx - you'll find that it has a 'scroll' method. The documentation says that it takes a parameter that "is the amount to scroll". This is a little misleading. Does it mean in pixels? Pages? Centimeters?

Well, if you have focusable items in your scoller, the measurement is actually in focusable items. So by calling the Scroll method on the ScrollingData object with a parameter of 5, you will scroll forward five elements.

Because you are now moving the SCROLLER rather than trying to move the focus on the repeated item itself, the repeater now has the opportunity to create the MCML objects, which allow it to focus on them properly.

The only catch is that unlike NavigateIntoIndex, Scoll is a relative movement. So if you are on the 1st item, scrolling with a parameter of 4 will take you to the 5th item. If you are on the 6th position, a value of 4 will take you to the 10th item.

So if your repeater is based on a Choice object, remember to factor in the Choice.ChosenIndex as part of your calculation for the amount you need to scroll by.

Published 28 October 2007 21:01 by IgnoranceIsBliss
Filed under: ,

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Leave a Comment

(required) 
(optional)
(required) 

  
Enter Code Here: Required
Submit
mControl for Windows Media Center
Powered by Community Server (Personal Edition), by Telligent Systems