WPF Date Range Double Slider Control (Part 1)

As I mentioned in my introduction to this series, I’m going over various aspects of how I created a DateTime Range slider control.  In this article, I’m going to be going over the basics of creating the user control.  Source for this project can be found on CodePlex.

First, to get two thumbs onto the slider, I overrode the control template of the regular slider with a template called “simpleSlider” to get rid of the track of each slider as well as some other default pieces of the base control template such as the repeater buttons.  With these things there, one or the other of the sliders would sit on top of the other and really just mess with my users’ experience.

Slider Control Template
  1. <ControlTemplate x:Key=“simpleSlider” TargetType=”{x:Type Slider}>
  2.     <Border SnapsToDevicePixels=“true” BorderBrush=”{TemplateBinding BorderBrush} BorderThickness=”{TemplateBinding BorderThickness}>
  3.         <Grid>
  4.             <Grid.RowDefinitions>
  5.                 <RowDefinition Height=“Auto”/>
  6.                 <RowDefinition Height=“Auto” MinHeight=”{TemplateBinding MinHeight}/>
  7.                 <RowDefinition Height=“Auto”/>
  8.             </Grid.RowDefinitions>
  9.  
  10.             <Rectangle x:Name=“PART_SelectionRange”/>
  11.  
  12.             <Track x:Name=“PART_Track” Grid.Row=“1”>
  13.                 <Track.Thumb>
  14.                     <Thumb x:Name=“Thumb” Style=”{StaticResource ResourceKey=HorizontalSliderThumbStyle} />
  15.                 </Track.Thumb>
  16.             </Track>
  17.         </Grid>
  18.     </Border>
  19. </ControlTemplate>

 

Then my control is made with the two sliders that use the “simpleSlider” template and a single Border control to be my track for the two sliders:

DateTime Range Slider
  1. <Grid VerticalAlignment=“Center” Background=“Transparent”>
  2.     <Border BorderThickness=“0,1,0,0” BorderBrush=“DarkGray” VerticalAlignment=“Bottom” Height=“1” HorizontalAlignment=“Stretch”
  3.            Margin=“0,0,0,10”/>
  4.  
  5.     <Slider x:Name=“LowerSlider” VerticalAlignment=“Top” IsEnabled=”{Binding ElementName=root, Path=IsLowerSliderEnabled, Mode=TwoWay}
  6.            Minimum=”{Binding ElementName=root, Path=Minimum, Converter={StaticResource ResourceKey=dtdConverter}}
  7.            Maximum=”{Binding ElementName=root, Path=Maximum, Converter={StaticResource ResourceKey=dtdConverter}}
  8.            Value=”{Binding ElementName=root, Path=LowerValue, Mode=OneWay, Converter={StaticResource ResourceKey=dtdConverter}}
  9.            Template=”{StaticResource simpleSlider}
  10.            Margin=“0,0,10,0”
  11.            SmallChange=”{Binding ElementName=root, Path=SmallChange, Converter={StaticResource ResourceKey=timespanToDoubleConverter}}
  12.            LargeChange=”{Binding ElementName=root, Path=LargeChange, Converter={StaticResource ResourceKey=timespanToDoubleConverter}}
  13.             />
  14.  
  15.     <Slider x:Name=“UpperSlider” IsEnabled=”{Binding ElementName=root, Path=IsUpperSliderEnabled, Mode=TwoWay}
  16.            Minimum=”{Binding ElementName=root, Path=Minimum, Converter={StaticResource ResourceKey=dtdConverter}}
  17.            Maximum=”{Binding ElementName=root, Path=Maximum, Converter={StaticResource ResourceKey=dtdConverter}}
  18.            Value=”{Binding ElementName=root, Path=UpperValue, Mode=OneWay, Converter={StaticResource ResourceKey=dtdConverter}}
  19.            Template=”{StaticResource simpleSlider}
  20.            Margin=“10,0,0,0”
  21.            SmallChange=”{Binding ElementName=root, Path=SmallChange, Converter={StaticResource ResourceKey=timespanToDoubleConverter}}
  22.            LargeChange=”{Binding ElementName=root, Path=LargeChange, Converter={StaticResource ResourceKey=timespanToDoubleConverter}}
  23.             />
  24. </Grid>

 

Mainly because I didn’t want to spend the time (at this point) dealing with making this a slider that could handle more than just a DateTime range, the Minimum, Maximum, and Value properties of the sliders are using an IValueConverter to handle the conversion between the doubles the sliders expose to DateTime values.  The SmallChange and LargeChange properties are converted from TimeSpans my control expects to doubles that the slider controls expect.

DateTime to Double Converter
  1. public class DateTimeDoubleConverter : IValueConverter
  2. {
  3.     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  4.     {
  5.         DateTime dt = DateTime.Parse(value.ToString());
  6.         return dt.Ticks;
  7.     }
  8.  
  9.     public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  10.     {
  11.         double d = double.Parse(value.ToString());
  12.         return new DateTime((long)d);
  13.     }
  14. }
TimeSpan to Double Converter
  1. public class TimeSpanToDoubleConverter : IValueConverter
  2. {
  3.     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  4.     {
  5.         TimeSpan givenValue = (TimeSpan)value;
  6.         return givenValue.Ticks;
  7.     }
  8.  
  9.     public object ConvertBack(object value, Type targetType,
  10.        object parameter, System.Globalization.CultureInfo culture)
  11.     {
  12.         return new TimeSpan(((long)value));
  13.     }
  14. }

facebooktwittergoogle_plusredditpinterestlinkedinmailfacebooktwittergoogle_plusredditpinterestlinkedinmailby feather

Leave a Reply

Your email address will not be published. Required fields are marked *