I need a listbox with IPhone-like functionality for Silverlight. That is, animated scrolling, and click and drag to scroll. Scrolling will continue a bit after the mouse up event based on the "speed" of the dragging. I've search and found no control vendors providing this. So question is how should I build it? I need some hints to get started.
There's two parts to this question:
Part 1, How to get the animated scrolling of the listbox.
Part 2, How to build a "draggable" scrolling, I guess I should put a canvas on top and track the mouseevent, and simulate some physics. Some hints here would have been great.
Thanks Larsi.
A while ago I made a control that did something like this. All I did was put a stackpanel inside a canvas. Just adjust the canvas.top of the entire stackpanel on a mousemove (while mouse is pressed). To animate the scrolling after a mouseup, you really just need to track the amount moved and apply an animation to the canvas.top property.
Here's a really nice complete sample for WPF that does both drag scrolling and automatic flick/inertia scrolling. I'm not sure what if anything would need to be changed to make it work in Silverlight.
http://sachabarbs.wordpress.com/2009/12/24/friction-scrolling-now-an-wpf-attached-behaviour-too/
Just a note that as-is you can't click and drag the view if you click on a child (e.g. buttons) that capture the mouse input. I actually ended up modifying this sample so you could still drag scroll when you click on children, while still allowing children to accept mouse input when not drag scrolling.
This will be easier in Silverlight 3 than Silverlight 2, but not impossible in 2.
This video from MIX 09, Building Microsoft Silverlight Controls, should help you.
Another post from Sacha Barber's website:
http://sachabarber.net/?p=481
Jeremiah Morrill shares code that implements animated scrolling with inertia in a custom ContentControl (templated with an included ScrollViewer)
<ScrollViewer x:Name="sv1" Width="500" Height="285">
<StackPanel x:Name="sp1" Width="450" Height="285">
</StackPanel>
</ScrollViewer>
By setting pos. and neg. margins to the stackpanel inside the scrollviewer
you can create a scroll effect.
onScroll_Up()
{
//Change this based on your scrollviewer dimension
if (this.sv1.ScrollableHeight < 300)
{
Thickness thickness = this.sp1.Margin;
thickness.Top += 50;
this.sv1.SetValue(StackPanel.MarginProperty, thickness);
}
}
onScroll_Down()
{
if (this.sv1.ScrollableHeight > 1)
{
Thickness thickness = this.sp1.Margin;
thickness.Top += -50;
this.sv1.SetValue(StackPanel.MarginProperty, thickness);
}
}