WPF Elements: Custom DualSlider tick mark style

The Mindscape WPF DualSlider has various features related to displaying tick marks similar to that provided by the standard WPF Slider control. The TickSpacing property allows you to set the logical distance between each of the tick marks. A pair of boolean properties called ShowTopLeftTickMarks and ShowBottomRightTickMarks specifies whether the tick marks are displayed on the top, bottom, or both edges of the slider track. Additionally, you can snap the slider thumbs to the tick marks by setting the SnapToTickMarks property to true. In this blog post we look at how to make a custom DualSlider style that has different sized tick marks based on their positions.

After setting the various properties mentioned above, the DualSlider controls generates a ReadOnlyCollection of doubles that can be acquired using the TickPositions property. This is a collection of physical positions that can be used in a style to place the tick marks. The numbers in the collection represent the distance from the left side of the slider track to each individual tick mark as illustrated below.

Tick mark positions

To style the tick marks, we can use the tick positions collection as the items source of an ItemsControl. Then we template each number to be a Border that only renders as a line on its right hand edge. The width of this border is a binding to the number itself which places the ‘tick mark’ in the correct place. Now, in order for us to render each tick mark with a different height, we start by making a class to represent an individual tick mark. Tick marks will need to know their position as well as their size which gives us the following class.

public class TickMark
{
  public double Position { get; set; }
  public double Size { get; set; }
}

Instead of filling an ItemsControl with a collection of positions, we now want to give it a collection of TickMark objects. This is easily achieved using a custom converter that will take the collection of positions and create instances of our TickMark objects. Within this converter, we will iterate through each of the positions and create a TickMark using the respective position. The size of each TickMark will be based on the index of the current position. Part of this converter class can be seen below.

// Size properties:
public int Size0 { get; set; }
    ...
public int Size9 { get; set; }
 
// Convert method:
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
  ReadOnlyCollection<double> positions = (ReadOnlyCollection<double>)value;
  IList<TickMark> tickMarks = new List<TickMark>();
  int count = 0;
  foreach (double d in positions)
  {
    double size = GetSize(count % 10);
    TickMark tickMark = new TickMark() { Position = d, Size = size };
    tickMarks.Add(tickMark);
    count++;
  }
  return tickMarks;
}
 
// Returns the size of a tick mark for the given modular interval.
private int GetSize(int remainder)
{
  switch (remainder)
  {
    case 0:
      return Size0;
 
    ...
 
    case 9:
      return Size9;
  }
  return 0;
}

In the Convert method we use the ‘count’ variable to keep track of what index we are at within the loop. We perform the modular operation on this variable and use the result to select the size of the TickMark. The converter has 10 properties that will let us set the size to be given to each TickMark based on their modular index. This converter can be used in xaml as follows.

<local:TickMarkListConverter x:Key="TickMarkListConverter" Size0="9" Size5="6" />
 
<DataTemplate x:Key="HorizontalTickTemplate">
    <Border BorderThickness="0,0,1,0" BorderBrush="Black" Height="{Binding Size}" MinWidth="1"
               Width="{Binding Position}" HorizontalAlignment="Left" VerticalAlignment="Top" />
</DataTemplate>
 
<Style x:Key="HorizontalTickListStyle" TargetType="ItemsControl">
  <Setter Property="ItemTemplate" Value="{StaticResource HorizontalTickTemplate}" />
  <Setter Property="ItemsPanel">
    <Setter.Value>
      <ItemsPanelTemplate>
        <Grid />
      </ItemsPanelTemplate>
    </Setter.Value>
  </Setter>
</Style>

When creating a DualSlider template, we can use an ItemsControl and set its ItemsSource to be a binding to the DualSlider.TickPositions property using the converter. The HorizontalTickTemplate as seen above uses the TickMark.Size property to set its height. Combining this with custom slider thumb and track styles can achieve results such as this:

Custom DualSlider style

Using this technique you can create all sorts of DualSlider styles involving tick marks with varying sizes or colors based on the requirements of your applications. A sample including all the source code for creating a custom DualSlider style in this way can be downloaded here. Let us know if you need help with styling any of the controls in WPF Elements by leaving a comment on this blog post or letting us know in the forum.

Click here to download the trial of WPF Elements.

Tagged as WPF, WPF Elements

2 Responses to “WPF Elements: Custom DualSlider tick mark style”

  • Dear Jason:

    Thank you so much for your post about WPF Dual Slider.

    I have download your post and build; I get the error message:
    The tag ‘BooleanToVisibilityConverter’ does not exist in XML namespace ‘clr-namespace:Mindscape.WpfElements;assembly=Mindscape.WpfElements’.

    Please send me the “BooleanToVisibilityConverter” code.

    Thank you;
    Adam

  • Hello,

    Thanks for checking out WPF Elements. To fix that error message, you need to add Mindscape.WpfElements.dll as an assembly reference in your project. To do this, in the solution explorer right-click on References ->Add Reference… -> Browse -> C:\Program Files (x86)\Mindscape\WPF Elements\Bin\Mindscape.WpfElements.dll (or the location where you installed it).

    Unfortunately, the sample that Jason attached to this blog post no longer works as it was based on an old build of WpfElements.dll (and an old version of the Dual Slider). However, you already have a fully working demo of the dual slider installed – you’ll find it in the Sample Explorer (Program Files (x86)\Mindscape\WPF Elements\Samples\Samples.sln) under Standard Controls -> Dual Slider.

    By running the Sample Explorer project you can see the slider in action and check out the options. It does however only have standard tick marks, but fortunately the custom tick mark code and styling used in the example attached to this post will work with the latest version. If you need any more help feel free to make a post in our WPF Elements support forum located at http://www.mindscapehq.com/forums/forum/15 .

  • Leave a Reply

Archives

Join our mailer

You should join our newsletter! Sent monthly:

Back to Top