Log in to like this post! XamWebSlider Atanas Dyulgerov / Monday, December 21, 2009 This article is the first in a series that will talk about the new controls and features in Infragistics’ second release for 2009. We start off with a slider control. This is a component that adds vertical or horizontal trackbar capability for your web application. The trackbar can have one or more handlers (they are called Thumbs in XamWebSlider), whose positions of which are translated into values from a specified range. The slider also has many features that allow the developer to create exciting user experience with very little effort. The following is an overview of most of the control’s features. Four standard variants of XamWebSlider Infragistics’ implementation of the slider control is divided into four controls that derive from a single slider base class. Each of these is best suited for a different scenario and gives you the flexibility to choose whatever fits well with your particular needs. The creation of four separate slider controls is based on the data type of the values and the number of thumbs you add to the slider. The four controls are called: · XamWebNumericSlider· XamWebNumericRangeSlider· XamWebDateTimeSlider· XamWebDateTimeRangeSlider As you have guessed, the data type of the first two controls’ thumb values are Double and the latter two are DateTime. The basic sliders allow just one thumb, while the range sliders allow more than one thumb, but require you to explicitly define them. The code snippets below show the most basic usage of the four sliders. But before you copy and paste this code into your application, you need to add references to the Infragistics.Silverlight.v9.2 and Infragistics.Silverlight.XamWebSlider.v9.2 assemblies. If you haven’t purchased the controls suite, you can download the trial version from http://www.infragistics.com/dotnet/netadvantage/silverlight/line-of-business.aspx#Downloads. After you have added the assembly references you need to add the following namespace reference: xmlns:igSlider="clr-namespace:Infragistics.Silverlight.Controls;assembly=Infragistics.Silverlight.XamWebSlider.v9.2" You are ready to use the sliders now. Here are the code snippets: Simple slider with double values. Minimum value is 0, Maximum value is 100 and the current value is 50. <igSlider:XamWebNumericSlider Value="50" MinValue="0" MaxValue="100" /> Range slider with double values and two thumbs. Min value is 0, max value is 100, first thumb value is 30 and second thumb value is 70. <igSlider:XamWebNumericRangeSlider MinValue="0" MaxValue="100" > <igSlider:XamWebSliderNumericThumb Value="30" /> <igSlider:XamWebSliderNumericThumb Value="70" /> </igSlider:XamWebNumericRangeSlider> Simple slider with DateTime values. Minimum value is 01/01/2009, Maximum value is 01/10/2009 and the current value is 01/05/2009. <igSlider:XamWebDateTimeSlider Value="01/05/2009" MinValue="01/01/2009" MaxValue="01/10/2009" /> Range slider with DateTime values and three thumbs. Min value is 01/01/2009, max value is 01/10/2009, first thumb value is 01/02/2009, second thumb value is 01/05/2009 and third thumb value is 01/07/2009. <igSlider:XamWebDateTimeRangeSlider MinValue="01/01/2009" MaxValue="01/10/2009" /> <igSlider:XamWebSliderDateTimeThumb Value="01/02/2009" /> <igSlider:XamWebSliderDateTimeThumb Value="01/05/2009" /> <igSlider:XamWebSliderDateTimeThumb Value="01/07/2009" /></igSlider:XamWebDateTimeRangeSlider> If you just need a basic slider that has a minimum, maximum, and a single current value, you can use the XamWebNumericSlider and your code will be just one line; if you want to use the slider for something more complex like changing multiple interconnected values in a business application you would use the range slider. If you need to filter the displayed data of a grid by one of its date columns, you can use the XamWebDateTimeRangeSlider. These four types of sliders however do not exhaust all your choices. You can use inheritance from the Infragistics slider base control and create your own custom slider with whatever type of data or number of thumbs you want. Custom type slider The slider assembly provides the XamWebSimpleSliderBase<T> and XamWebRangeSlider<T > classes. By inheriting these classes, supplying a data type, and overriding a few methods, you can easily have a very flexible slider that can work with any type of data. The following sample illustrates how to create a simple slider that works with the Color data type as the value. public class ColorSlider : XamWebSimpleSliderBase<Color> { protected override Color DoubleToValue(double value) { int pixel = (int)value; //Shift int to RGBA values byte B = (byte)(pixel & 0xFF); pixel >>= 8; byte G = (byte)(pixel & 0xFF); pixel >>= 8; byte R = (byte)(pixel & 0xFF); pixel >>= 8; byte A = (byte)pixel; // alpha return Color.FromArgb(A, R, G, B); } protected override double ValueToDouble(Color value) { return return value.A << 24 | value.R << 16 | value.G << 8 | value.B; } } After you have created your custom slider you can use it like this: <Grid x:Name="LayoutRoot" Background="{Binding Value, ElementName=cSlider, Converter={StaticResource myConverter}}" > <colorSlider:ColorSlider x:Name="cSlider" MinValue="Aqua" Value="YellowGreen" MaxValue="Chocolate"/> </Grid> You will notice that we use a converter to assign the slider value to the background as its type is solid color brush and the value is color. Here is the code for the converter: public class BackgroundCoverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return new SolidColorBrush((Color)value); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { SolidColorBrush brush = value as SolidColorBrush; if(brush!= null) { return brush.Color; } return Colors.White; }} This code will give you a slider that changes the background of the layout root from Aqua all the way to Chocolate and is currently set at YellowGreen J How cool is that! But that is not the full story. The XamWebSlider control has advanced features such as support for commanding that we are going to talk about further on in this article. For example, the increase and decrease buttons rely on commands in order to operate. If you create a custom slider, overriding the two methods mentioned earlier is not enough. We also need to override the GetParameter and SupportsCommand methods. protected override object GetParameter(CommandSource source) { if (source.Command is XamWebSliderBaseCommandBase) { return this; } return null; } protected override bool SupportsCommand(ICommand command) { return command is XamWebSliderBaseCommandBase;} Adding this will enable the buttons and everything else that uses the commanding framework with your custom control, however the details of this portion of functionality is beyond the scope of this article and it may be covered at another time. Basic features Now that I have showed you the types of sliders available to you, let’s take a look at some of its interesting features. The first one that I’m going to draw your attention to is only available for the range slider and is called ThumbInteractionMode. With the Infragistics slider you can control the way a thumb interacts with the other thumbs. There are three modes in the 9.2 release – Push, Free and Lock. If you choose Push for a specific thumb, when other thumbs try to move past it they will move it not allowing rearrangement of the order. If you choose Lock, the dragged thumbs will not be able to move beyond the point of the other thumb at all. Using Free allows the other thumbs to move as if there is no thumb in the way at all. Free is also the default behavior. <igSlider:XamWebNumericRangeSlider MinValue="0" MaxValue="100" > <igSlider:XamWebSliderNumericThumb Value="30" InteractionMode="Free" /> <igSlider:XamWebSliderNumericThumb Value="50" InteractionMode="Lock" /> <igSlider:XamWebSliderNumericThumb Value="70" InteractionMode="Push"/> </igSlider:XamWebNumericRangeSlider> In this sample you will be able to move the first thumb anywhere in the range from 0 to 50 (or the current value of the second thumb). You will be able to move the second thumb anywhere from 0 to 100 and you won’t impact the first thumb, but move the third thumb as you slide. Another thumb specific feature is the thumb tooltip. There are two ways to implement it. The first one is suitable if you want to add a simple tooltip such as help text or simple current value display. The limitation is that you cannot remove the white background of the tooltip container provided by the framework itself, which is used in the implementation. Here is how you code the tooltip to show the control’s value: Show’s how to apply a tooltip template on a simple numeric slider <igSlider:XamWebNumericSlider Value="50" MinValue="0" MaxValue="100" > <igSlider:XamWebNumericSlider.ThumbStyle> <Style TargetType="igSlider:XamWebSliderNumericThumb" > <Setter Property="ToolTipVisibility" Value="Visible" /> <Setter Property="ToolTipTemplate"> <Setter.Value> <DataTemplate> <TextBox Text="TooltipText" /> </DataTemplate> </Setter.Value> </Setter> </Style> </igSlider:XamWebNumericSlider.ThumbStyle> </igSlider:XamWebNumericSlider> Show’s how to apply a tooltip template on a numeric range slider <igSlider:XamWebNumericRangeSlider MinValue="0" MaxValue="100" > <igSlider:XamWebSliderNumericThumb Value="50" ToolTipVisibility="Visible" > <igSlider:XamWebSliderNumericThumb.ToolTipTemplate> <DataTemplate> <TextBox Text="TooltipText" /> </DataTemplate> </igSlider:XamWebSliderNumericThumb.ToolTipTemplate> </igSlider:XamWebSliderNumericThumb> </igSlider:XamWebNumericRangeSlider> The second one gives you much more control. It involves a thumb control template. The trick is to implement the tooltip as part of the thumb itself and adjust its visibility when the MouseEnter and MouseLeave events are fired. Here is an example: <igSlider:XamWebSliderNumericThumb Value="30" DragStarted="XamWebSliderNumericThumb_DragStarted"> <igSlider:XamWebSliderNumericThumb.Template> <ControlTemplate> <Grid Width="100" Height="20" > <Border x:Name="border" Background="Lime" Visibility="Collapsed" Margin="0,-30,0,0" Width="100" Height="20" VerticalAlignment="Center" HorizontalAlignment="Center" > <TextBlock Text="ToolTip Text" HorizontalAlignment="Center" VerticalAlignment="Center" /> </Border> <Rectangle Fill="Red"Width="10" Height="10" VerticalAlignment="Center" HorizontalAlignment="Center" MouseEnter="Rectangle_MouseEnter" MouseLeave="Rectangle_MouseLeave" /> </Grid> </ControlTemplate> </igSlider:XamWebSliderNumericThumb.Template> </igSlider:XamWebSliderNumericThumb> private void Rectangle_MouseEnter(object sender, MouseEventArgs e) { Border Border tooltip = (sender as Rectangle).FindName("border") as Border; tooltip.Visibility = Visibility.Visible; } private void Rectangle_MouseLeave(object sender, MouseEventArgs e) { Border tooltip = (sender as Rectangle).FindName("border") as Border; tooltip.Visibility = Visibility.Collapsed; } private void XamWebSliderNumericThumb_DragStarted(object sender, System.Windows.Controls.Primitives.DragStartedEventArgs e) { var tooltip = (VisualTreeHelper.GetChild(sender as XamWebSliderNumericThumb, 0) as Grid).FindName("border") as Border; tooltip.Visibility = Visibility.Collapsed; } The logic in the code-behind determines when the tooltip opens and closes. If you want to make it fancy you could use animations, timing, and custom paths. Your creative ideas are the limit J. Another useful feature of the XamWebSlider control is that is offers a flexible and powerful way to show tickmarks along the track. There are three things you need to know about the tickmarks. First you could specify how many tickmarks you want with the NumberOfTickMarks property. The tickmarks will be computed to be separated by equal spaces along the slider track. You have the option to include or exclude the ends of the slider in this computation. The default is to exclude the ends. <igSlider:XamWebNumericSlider Value="50" MinValue="0" MaxValue="100" > <igSlider:XamWebNumericSlider.TickMarks> <igSlider:SliderTickMarks NumberOfTickMarks="10" IncludeSliderEnds="True" /> </igSlider:XamWebNumericSlider.TickMarks> </igSlider:XamWebNumericSlider> Second, if you don’t know how many tickmarks you want to show, you can configure the control to show tickmarks by frequency (i.e. how often along the slider scale the tickmarks should appear). So if you use a DateTime slider you could tell the tickmarks to mark each 2 months for example or every 7 days. The sample below shows how to mark every 10 units in a numeric slider. <igSlider:XamWebNumericSlider Value="50" MinValue="0" MaxValue="100" > <igSlider:XamWebNumericSlider.TickMarks> <igSlider:SliderTickMarks IncludeSliderEnds="True" TickMarksFrequency="10" /> </igSlider:XamWebNumericSlider.TickMarks> </igSlider:XamWebNumericSlider> The third thing you need to know is that the tickmarks can be styled to look like whatever you want. You could define a data template and make the tickmarks look like currency if you want. <igSlider:XamWebDateTimeSlider Value="01/05/2009" MinValue="01/01/2009" MaxValue="01/10/2009" > <igSlider:XamWebDateTimeSlider.TickMarks> <igSlider:DateTimeSliderTickMarks FrequencyType="Days" TickMarksFrequency="2"> <igSlider:DateTimeSliderTickMarks.HorizontalTickMarksTemplate> <DataTemplate> <Rectangle Fill="Red" Width="2" Height="10" /> </DataTemplate> </igSlider:DateTimeSliderTickMarks.HorizontalTickMarksTemplate> </igSlider:DateTimeSliderTickMarks> </igSlider:XamWebDateTimeSlider.TickMarks> </igSlider:XamWebDateTimeSlider> The thumbs also have property IsSnapToTickMarkEnabled that if set to True restricts the thumb movement to only over tickmarks. Try the following snippet to check it out. <igSlider:XamWebDateTimeRangeSlider MinValue="01/01/2009" MaxValue="01/10/2009" > <igSlider:XamWebDateTimeRangeSlider.TickMarks> <igSlider:DateTimeSliderTickMarks NumberOfTickMarks="10" /> </igSlider:XamWebDateTimeRangeSlider.TickMarks> <igSlider:XamWebSliderDateTimeThumb IsSnapToTickEnabled="True" Value="01/03/2009" /> <igSlider:XamWebSliderDateTimeThumb Value="01/07/2009" /> </igSlider:XamWebDateTimeRangeSlider> In some situations you might want to hide the left trail before the thumb and simulate thumb independence. In order to achieve this, you may be compelled to setting the track fill brush to be transparent, but unfortunately that won’t help you as the other thumbs’ TrackFills will be affected by the position of the thumb with the transparent TrackFill. The solution is to set the IsTrackVisible property to False. This will ignore the thumb in the calculation of the other thumbs’ TrackFills. Navigation In this section, I would like to talk a bit about some cool features that control the thumb movement behavior. I’ll start with the range selection behavior. If you have a slider with two or more thumbs, you could set the IsSelectionRangeEnabled property to True. When you drag the area between two of the thumbs, both thumbs will move and the distance between them will be maintained. Thumb movement is not limited to just mouse interaction, you can also interact with the control using the keyboard or with the mouse scroll wheel. By default, you have buttons that move the active thumb by increasing or decreasing the value. You can also reverse the direction of the value increments. The following sample combines all this interactivity: Enabled keyboard and mouse wheel movement, explicitly visible buttons, reversed direction of the values and also range selection. <igSlider:XamWebDateTimeRangeSlider MinValue="01/01/2009" MaxValue="01/10/2009" IsSelectionRangeEnabled="True" IncreaseButtonVisibility="Visible" DecreaseButtonVisibility="Visible" IsMouseWheelEnabled="True" EnableKeyboardNavigation="True" IsDirectionReversed="True"> <igSlider:XamWebSliderDateTimeThumb Value="01/03/2009" /> <igSlider:XamWebSliderDateTimeThumb Value="01/07/2009" /> </igSlider:XamWebDateTimeRangeSlider> There are some limitations from the framework that I need to share here. If you have windowless mode set to True in your application, the mouse wheel movement will not work in Firefox and some other browsers. The reason is that the MouseWheel event needs the windowless to be False in order to function correctly in these browsers. However there is a workaround. You can manually modify the slider value by handling the browser’s OnMouseWheel event J that the following code shows an example of how to accomplish this: This goes in the constructor HtmlPage.Window.AttachEvent("DOMMouseScroll", OnMouseWheel); HtmlPage.Window.AttachEvent("onmousewheel", OnMouseWheel); HtmlPage.Document.AttachEvent("onmousewheel", OnMouseWheel); This is the handler that does the dirty work private void OnMouseWheel(object sender, HtmlEventArgs args) { double mouseDelta = 0; ScriptObject e = args.EventObject; if (e.GetProperty("detail") != null && App.Current.Host.Settings.Windowless == true) { mouseDelta = ((double)e.GetProperty("detail")); this.slider.Thumbs[0].Value += (mouseDelta / 3) * this.slider.SmallChange; } } this.slider.Thumbs[0] is the thumb that you want to modify. We divide mouseDelta by 3 because 3 original delta values correspond to 1 mouse scroll step. We will talk about small change a bit further in this article. The ScriptObject and HtmlPage classes are located in System.Windows.Browser. This will generally solve the problem, but the slider will be moved any time you scroll your mouse wheel. You may want to include logic to checkIf the slider is focused also, but that is up to you. The last navigation feature I want to talk about is TrackClickAction. This property modifies the behavior of the thumb when you click on the track and not over a particular thumb. By default, nothing happens when you click on the track area because the TrackClickAction property is set to None. The other two options are LargeChange and MoveToPoint. If you use the MoveToPoint, the active or closest thumb (if no thumbs are active), will move to the point of the track that you clicked. If you use LargeChange, the thumb will move by whatever value you have specified in LargeChange in the direction of the clicked location. <igSlider:XamWebNumericSlider Value="50" MinValue="0" MaxValue="100" TrackClickAction="MoveToPoint" /> Small and Large change Small and Large change are properties that hold value steps. The values assigned to these properties need to be the same data type that has been assigned to the Value, MinValue and MaxValue properties. When you click on the increase or decrease buttons, or if you use the keyboard or mouse wheel, the small change value is used to increment the thumb value. The large value is used similarly whenever you click on the track, not over a particular thumb and the TrackClickAction is set to LargeChange. Styling The four general elements that you can modify to fully customize the looks of your slider are the TrackFill, Thumbs, Tickmarks and the Slider base. All of these accept control templates and thus you can style them however you want; You can totally change the default appearance of the slider. Here are some examples: The easiest way to style a slider is to do this in Blend. When you right click the slider in design mode and edit a copy of the template, Blend will fetch the default template and generate all the code you will need. You can then modify this template code to whatever you want. Blend will also show you all the template parts that need to be present in order for the slider to work correctly. If you don’t have Blend you could go to http://labs.infragistics.com/silverlight/lobsamples/2009.2/ and open the slider styling samples. For the sake of brevity, I’m not posting the code here; thisstyle is about 400 lines of code J But don’t worry it’s pretty well organized and self explanatory. If you want to modify an element such as the thumb, tickmarks, or the track itself, it will be easier than the previous example. The thumb can be styled by using the ThumbStyle property of the basic slider to apply a ControlTemplate; similarly for a range slider, you can use a specific thumb’s Template property: Show’s how to apply a Thumb template on a simple numeric slider <igSlider:XamWebNumericSlider Value="50" MinValue="0" MaxValue="100" > <igSlider:XamWebNumericSlider.ThumbStyle> <Style TargetType="igSlider:XamWebSliderNumericThumb" > <Setter Property="Template"> <Setter.Value> <ControlTemplate> <Rectangle Fill="Red" Height="10" Width="10" /> </ControlTemplate> </Setter.Value> </Setter> </Style> </igSlider:XamWebNumericSlider.ThumbStyle> </igSlider:XamWebNumericSlider> Show’s how to apply a Thumb template on a numeric range slider <igSlider:XamWebNumericRangeSlider MinValue="0" MaxValue="100" > <igSlider:XamWebSliderNumericThumb Value="50" > <igSlider:XamWebSliderNumericThumb.Template> <ControlTemplate> <Rectangle Fill="Red" Height="10" Width="10" /> </ControlTemplate> </igSlider:XamWebSliderNumericThumb.Template> </igSlider:XamWebSliderNumericThumb> </igSlider:XamWebNumericRangeSlider> The tickmarks are simple as that as well: Show’s how to apply a tickmark template on a slider <igSlider:XamWebNumericSlider Value="50" MinValue="0" MaxValue="100" > <igSlider:XamWebNumericSlider.TickMarks> <igSlider:SliderTickMarks TickMarksFrequency="1"> <igSlider:SliderTickMarks.HorizontalTickMarksTemplate> <DataTemplate> <Rectangle Fill="Black" Width="2" Height="10" /> </DataTemplate> </igSlider:SliderTickMarks.HorizontalTickMarksTemplate> </igSlider:SliderTickMarks> <igSlider:SliderTickMarks TickMarksFrequency="5" IncludeSliderEnds="True"> <igSlider:SliderTickMarks.HorizontalTickMarksTemplate> <DataTemplate> <Rectangle Fill="Black" Width="2" Height="15" /> </DataTemplate> </igSlider:SliderTickMarks.HorizontalTickMarksTemplate> </igSlider:SliderTickMarks> </igSlider:XamWebNumericSlider.TickMarks> </igSlider:XamWebNumericSlider> The last element that I am going to show you how to style is the Thumb’s TrackFill . The two style related properties are the TrackFillBrush and TrackFillStyle. Here is sample code for both of them. Show how to add the namespace for the TrackFill element. We need this to use it in the style target type. xmlns:igPrimitives="clr-namespace:Infragistics.Silverlight.Controls.Primitives;assembly=Infragistics.Silverlight.XamWebSlider.v9.2" Use of TrackFillBrush in a slider <igSlider:XamWebNumericSlider Value="50" MinValue="0" MaxValue="100" > <igSlider:XamWebNumericSlider.ThumbStyle> <Style TargetType="igSlider:XamWebSliderNumericThumb" > <Setter Property="TrackFillBrush" Value="Red" /> </Style> </igSlider:XamWebNumericSlider.ThumbStyle> </igSlider:XamWebNumericSlider> Use of TrackFillStyle in a slider <igSlider:XamWebNumericRangeSlider MinValue="0" MaxValue="100" > <igSlider:XamWebSliderNumericThumb Value="40" TrackFillBrush="Red" /> <igSlider:XamWebSliderNumericThumb Value="70" > <igSlider:XamWebSliderNumericThumb.TrackFillStyle> <Style TargetType="igPrimitives:TrackFill"> <Setter Property="Template"> <Setter.Value> <ControlTemplate> <Ellipse Fill="Lime" Height="20" /> </ControlTemplate> </Setter.Value> </Setter> </Style> </igSlider:XamWebSliderNumericThumb.TrackFillStyle> </igSlider:XamWebSliderNumericThumb> </igSlider:XamWebNumericRangeSlider> This is the end of this article. I really hope it has been helpful and interesting for you. Please feel free to leave comments or ask questions.