Create A Snapping Slider In Blend Using Behaviors (Silverlight 3 or WPF)
UPDATE: It turns out that in WPF, there is an easier way to snap the slider. For integers, simply check the “IsSnapToTickEnabled” and set your TickFrequency accordingly. Which means that this behavior is really only useful for Silverlight, which doesn’t have those properties.
Behaviors are easily the coolest thing that has ever happened to anything.
Perhaps I overstate my case somewhat. But they’re still pretty cool.
To me, a wonderful example is the ability to let designers/developers get some really cool functionality out of the Silverlight or WPF slider.
Now, one might normally think that there is a simple way to make your slider values to snap to an integer or to some incremental number (perhaps base 2 or base 10). Alas, one would be wrong. There have been a couple solutions to this problem (see here and here), but they usually involve creating a new slider subclass with the additional functionality if you really want the interaction to be reusable.
However, behaviors makes all this unnecessary. What is even better is that there is no code difference between WPF and Silverlight on this one. That’s right… this tutorial and the code that goes with it works exactly the same in Silverlight as it does in WPF.
SnappingSlider Behavior (SnappingSlider.cs) – Works for Silverlight and WPF
WPF SnappingSlider Behavior (All Project Files)
Silverlight SnappingSlider Behavior (All Project Files)
You can also download the behavior here (just the cs file) which would make me happy because it ups my street cred among the Silverlight homies (says the whitest man on earth).
If you want to learn how to create it yourself, let’s get started.
In your project in Blend, right-click on the project and go to “Add New Item…”
Choose “Behavior” from the list and type in the name of the behavior you want to create
This is where Blend is way cooler than Visual Studio… it gives you pretty much all the code and imports all the appropriate references for creating a behavior. So, first change the behavior associated object type to a Slider:
public class SnappingSlider : Behavior<Slider>
And go into the inside the OnAttached method, enter the following code:
AssociatedObject.ValueChanged +=new System.Windows.RoutedPropertyChangedEventHandler<double>(AssociatedObject_ValueChanged);
Hint to Code Newbies: If you get to the “+=” part and hit the Tab key twice it will add the necessary code.
Inside the AssociatedObject_ValueChanged method, I added the following code:
private voidAssociatedObject_ValueChanged(objectsender, System.Windows.RoutedPropertyChangedEventArgs<double> e)
{
//Let the slider be equal to the Maximum and Minimum values
if((e.NewValue != AssociatedObject.Maximum) && (e.NewValue != AssociatedObject.Minimum))
{
//Using the Minimum value as a starting point, only allow values that are
// a multiple of the SmallChange value. If you want to simply round to
// integers, set it so that:
// SmallChange = 1
doublecalcValue = Math.Floor((e.NewValue – AssociatedObject.Minimum) / AssociatedObject.SmallChange);
calcValue = (calcValue * AssociatedObject.SmallChange) + AssociatedObject.Minimum;
AssociatedObject.Value = Math.Round(calcValue);
}
else
{
//Sometimes it hiccups on me, so I used this to catch those
AssociatedObject.Value = Math.Round(e.NewValue);
}
}
Once you have that code in place, build the project (menu option Project –> Build Project).
Now you should have the behavior available in the “Assets” tab under “Behaviors” (at the bottom of the picture below).
Just drag it onto your Slider and set the Minimum, Maximum and SmallChange properties appropriately. Remember that SmallChange is the value is that is acting as your increment controller.
At the very sight of this thing, with a stylus in hand, your average lefty is thinking to him or herself “I wonder if I can do my work upside down?” Let’s show them that we love and accept them just as they are.
Let’s dig right into the ScrollViewer. If you’re doing this from the listview (like I am) then creating a template for the listview has already created a template for the scrollviewer. If you’re starting from a basic scrollviewer, you can pretty much start right here.
The normal ScrollViewer will look like this:


If you want to make this a more robust control, I recommend creating a ScrollViewer with an additional dependency property (IsSouthPaw or something). Make it so that your Grid has three columns:




