iamaprogrammer
I had to solve this problem recently... Actually, I believe my requirements were even more difficult - as my application has all the restrictions of a 10ft application (i.e., no mouse - only keyboard navigation) - and the selected item always has to be in the center of the list (unless the list has less than the number of visible items, in which case the selection can move)... so basically I had to turn off all of the standard ScollViewer bits.
I wasn't familiar enough with WPF to solve this problem elegantly (well, now that I think about it, my solution is fairly simple) - but does require a bit of code. Basically what I ended up doing was creating a UserControl and wrapping a ListBox control inside a Canvas inside a Border. So my heirarchy looks like UserControl->Border->Canvas->ListBox. The Border has its ClipToBounds set to true, and so I basically scroll the ListBox using Canvas coords and use ListBoxItem width and height attributes to measure the scroll amounts. The UserControl has a dependency property which is the desired number of visible items in the list - and uses this number to dynamically size the Canvas (and its parent, the border) so that only those number of items are visible.
One of the drawbacks with this implementation is that your UserControl needs to know about changes to the data in the ListBox - in case it needs to re-center the list - and this is what I am currently stuck on - and have asked for help with in this post. I can't figure out how to get callbacks in my UserControl whenever the item collection of the ListBox changes.... I have added a SourceUpdated event to my ListBox, but its not getting called. Uhg... there is sooo much to learn about this framework.