The wheel control, thanks to Rene Schulte for telling me what the term on the street was, is used in a few places in Windows Phone 7 (WP7) and Nick Randolph created a user control to mimic it. It was great but needed a few little tweaks. Nick did all the heavy lifting on this.
Currently you can go to his blog entry on it here: Windows Phone7 Wheel Control – Updated to get the most up to date version.
What I did:
- Enabled flick gestures
- Removed a flicker on press
- On lost focus, snap to grid
- Allowed for SelectedIndex to be set via XAML
What Nick was doing was levering the ManipulationCompleted event on the scroller in the ListBox and then snapping to grid. The problem is that when you flick, that event is fired the second your finger is removed from the screen. The item should snap when it is done moving. Peter Torr has a blog post on detecting if a list is scrolling or not so I leveraged that bit of code.
I then changed how the CurrentStateChanging event worked in Peter’s code to work with the wheel code.
group.CurrentStateChanging += (s, args) =>
_currentState = args.NewState;
if (_currentState.Name == "NotScrolling" && !_userClickedOnItem)
Now to get this to work properly, there are lots of use cases you have to watch out for.
- Flicking and click
- Flicking and lost focus
- Flicking and it stops scrolling
- Clicking but not flicking
Fixing the flickering issue fixed and caused a few of the issues.
The root cause of the flickering was how Nick was handling the LostFocus when you would select an item by clicking. Flicking does not cause this behavior until it runs out of items / stops moving. LostFocus is fired before SelectionChanged and he would hide everything then show update it.
The MouseEnter event however happens before LostFocus (the magic of breakpoints :-)) so with a simple Boolean to verify that they are clicking and on UpdateFocus, only update if a click event is not in progress. On MouseLeave and on Scroller_ManipulationCompleted, that boolean, _userClickedOnItem, is set to false.
As is, this control is not currently a Date or Time picker control. With a bit of work however, it can easily become that.