WPF Date Range Double Slider Control (Introduction)

For a project I’m working on, I needed a way to select a date range.  One of my first thoughts was to use a double slider only to find that one didn’t exist with the OOTB controls so I decided to roll my own.   In order to solidify things in my mind as well as help anyone out there looking for resources on various aspects of development in WPF, I thought I’d write about my experience creating this control.

I’ll be adding blog entries in the next week or two to describe how I accomplished implemenation of some of the features I wanted in my control:

  • Create a two-thumbed slider control to choose a DateTime range. (Part 1)
  • Don’t let the the lower slider or upper slider pass each other.  I was creating this to use with a graph and if the sliders passed each other even for a millisecond, the graph would throw an exception. (Part 2)
  • Dependency Properties  (Part 3)

I did lose some of the functionality of the regular slider in my first version of this control, such as clicking to the right or left of the thumb to change the value and displaying the slider in a vertical format, but overall, I’m happy with this control as it is so far (and so was my client.)

Because I wanted to continue work on this control and make it easy to download and use the code, the source for the control and a sample project are available at CodePlex.

Facebooktwittergoogle_plusredditpinterestlinkedinmailFacebooktwittergoogle_plusredditpinterestlinkedinmailby feather

14 Responses to WPF Date Range Double Slider Control (Introduction)

  1. Hi, I stuck using your date range slider, it’s great control. I want to change Slider’s lower value in dispatcher timer which ticks every second and I want to increase lower value by one second, it did that but the lower slider’s thumb stays at their default, I want to move it along the current value. When I dragged it works normally.

    Please help me!
    Thanks in advance.

    • Greg Andora says:

      How are you going about doing this? I did a quick mock up of it and it is moving for me. If it is moving every second, one thing to take into consideration is that if you have a really wide possible range, the amount it’ll move is very small, for example, if your min & max cover a whole day, each second it will only move 1/86,400 of the way across the bar….its going to be hard to see that. Not bothering with a view model, this is what I did to try this out in the code behind of the MainWindow in the sample. In order to see the changes better, I modified the Lower & Upper Values and the Minimum and Maximum values in the XAML.

      XAML
      <userControls:DateRangeSlider x:Name="dateRangeSlider1"
      LowerValue="04/21/2011 8:00 PM"
      UpperValue="04/21/2011 8:30 PM"
      Minimum="04/21/2011 8:00 PM"
      Maximum="04/21/2011 9:00:00 PM"...

      Code Behind
      private DispatcherTimer lowerValueTimer;

      public MainWindow()
      {
      InitializeComponent();
      lowerValueTimer = new DispatcherTimer(TimeSpan.FromSeconds(1), DispatcherPriority.Background, new EventHandler(MoveLowerValue), Application.Current.Dispatcher);
      }

      private void MoveLowerValue(object sender, EventArgs e)
      {
      dateRangeSlider1.LowerValue += TimeSpan.FromSeconds(1);
      }

      • Hey Greg! You are great, you made my morning! you’re right it’s moving slowly which I didn’t recognized. Thanks!

        I need one more feature, your range slider is working great till now, What I want is, in between the range I need to show the player current header [current Position] as diamond shape [another thumb for showing current player marker]. Will you please show me the way how can I achieve this.

        Thanks for your last solution It worked.
        Shahnawaz Khan

  2. Greg Andora says:

    In the DateRangeSlider.xaml.cs, you’d need to add a new dependency property for the value that thumb would be bound to.

    To get the new thumb, in the DateRangeSlider.xaml, you’d need to add a 3rd slider like the other two in there and bind its value to your new dependency property.

    To get the diamond shape, you just need to create a new Style for the Thumb to use and change that in the simpleSlider.

  3. Apurva says:

    Hello,

    I am trying to use this date range slider in my WPF project but it seems that the LowerValueChanged and UpperValueChanged events are not hooked up.

    Here is my XAML:

    Here is my code behind

    private void OnLowerValueChanged(object sender, RoutedPropertyChangedEventArgs e)
    {
    this.Events.Publish(new GenericStringEvent(“DateRangeChanged”));
    }

    Thanks

    Apurva

  4. Greg Andora says:

    Seems I forgot to actually fire those events. I can’t make the changes to the download at the moment, but it is pretty easy to add. I’ll just talk about the Lower Slider event and hopefully that’ll help you get both of them firing off their respective events.

    In DateRangeSlider.xaml.cs there is a private method called LowerSlider_ValueChanged:
    At the top of it, add:
    DateTime oldValue = new DateTime((long)LowerSlider.Value); // get the original DateTime
    At the bottom of it, add:
    DateTime newValue = new DateTime((long)LowerSlider.Value); // get the new DateTime
    Then under that, fire the routed event:
    // Set Event Arguments
    var eArgs = new RoutedPropertyChangedEventArgs(oldValue, newValue, DateRangeSlider.LowerValueChangedEvent);
    // Raise the event
    RaiseEvent(eArgs);

  5. Ephrem says:

    Hi Greg,
    I tried to fire the event and I did following your instruction above and I got the following error.
    Using the generic type ‘System.Windows.RoutedPropertyChangedEventArgs’ requires 1 type arguments
    in the line of code below.
    var eArgs = new RoutedPropertyChangedEventArgs(oldValue, newValue, DateRangeSlider.LowerValueChangedEvent);

    Any idea how to fix it.
    Your help is much appreciated and I found your two thumb slider very helpful
    Thanks,
    Ephrem

  6. Ephrem says:

    I fixed it; actually it was easy, I changed it like this and it works fine:
    var eArgs = new RoutedPropertyChangedEventArgs(oldValue, newValue, DateRangeSlider.LowerValueChangedEvent);
    i.e. I have added return type

    Cheers,
    Ephrem

  7. Ephrem says:

    I see, after I post the above one; I realized that the website is removing the return type DateTime after RoutedPropertyChangedEventArgs
    so that means even the orginal one from Greg was correct, if it was not filtered and removed DateTime by the website
    Any way you will know what I mean if you copy the code above and try to use it

  8. Hemant Kulkarni says:

    Hi Greg,

    I have a question regarding this Date Range Slider.
    How do I change the date and time format? It always displays in 12 hour format. I want to display in 24 hour format.

    Regards,
    HK

    • Greg Andora says:

      The control itself is just outputting DateTime objects as properties. In the sample application, you can change the format of the DateTime by adding a StringFormat to the binding of the TextBlocks.

      {Binding ElementName=dateRangeSlider1, Path=LowerValue, Mode=OneWay}”
      becomes
      {Binding ElementName=dateRangeSlider1, Path=LowerValue, Mode=OneWay, StringFormat={}{0:yyy-MM-dd HH:mm:ss}}”

  9. Dirk-Jan says:

    Hey excellent control however I just noticed a bug with setting certain dates.

    I am also using the slider in a graph application, since I pull data out of a database I have a max and a min value thats possible, so far so good.

    However I wanted to set the minimum to the oldest date and the maximum to the newest date (values from the db).
    Then I noticed that the left slider didn’t move to the value I told it to. (I first set the min/max and then a default value for the thumbs (by default max and max -5 minutes)).

    So we get something like this:

    this.DateRangeSlider.Maximum = new DateTime(2015, 1, 5, 13, 50, 10);
    this.DateRangeSlider.UpperValue = new DateTime(2015, 1, 5, 13, 50, 10);
    this.DateRangeSlider.Minimum = new DateTime(2015, 1, 1, 13, 50, 10);
    this.DateRangeSlider.LowerValue = new DateTime(2015, 1, 5, 13, 45, 10);

    This works excellent! However if we supply DateTimes > 9 May 2015 the left thumb begins to get buggy (It is staying on an older date, if you set the date even higher for example on 15 may 2015 it gets pulled to the minimum value of the slider)

    So for example if we set the values with the following:

    this.DateRangeSlider.Maximum = new DateTime(2015, 5, 9, 15, 56, 37);
    this.DateRangeSlider.UpperValue = new DateTime(2015, 5, 9, 15, 56, 37);
    this.DateRangeSlider.Minimum = new DateTime(2015, 5, 9, 08, 01, 28);
    this.DateRangeSlider.LowerValue = new DateTime(2015, 5, 9, 15, 56, 37);

    You will see that the left slider is at the wrong position. I honestly have no idea how this could happend I hope that you have a idea what the issue might be.

    Thnx!

Leave a Reply

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