WPF Date Range Double Slider Control (Part 2)

As I mentioned in my introduction to this series, I’m going over various aspects of how I implemented a control that allows a user to choose a DateTime range using a double slider control.  In Part One, I covered the basics of what I did to the control templates, put the slider together and showed the IValueConverters I used to handle the conversions from doubles to DateTime and doubles to TimeSpans.  In this article, I’ll be talking about what I did to keep the upper value and the lower value sliders from crossing each other.  The source for the control and a sample project can be found at CodePlex

My first thought doing this was to play it simple and bind the lower slider’s Maximum to the upper slider’s current value and the and the upper sliders Minimum to the lower’s current value.   While this seemed logical to me, when I implemented it, it put the two sliders on two totally separate scales and it failed miserably.  Not only were the sliders able to cross, since the scales were constantly changed, while I would move the lower slider, the upper slider would be moving (and not changing value).

My second attempt was much better, but still didn’t work as expected.  In this attempt, I subscribed to the ValueChanged event for each of the sliders.  In these event handlers, I had a piece of code as shown in “Attempt 2:  Fail” that was setting the slider controls values so they wouldn’t cross each other (for long) and then setting dependency properties (UpperValue and LowerValue) to those upper and lower values.  This failed because I wasn’t setting the upper slider’s value to something greater than the lower slider’s value until after this code ran.  To a user, this would be acceptable, you can’t actually see the values cross.  However, I was using this to help zoom in and out of a charting control  and once they crossed, even for a few milliseconds, the charting control would blow up on me.  It was quite messy…line fragments, points, and data everywhere.

Attempt 2: Fail
  1. private void LowerSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
  2. {
  3.     UpperSlider.Value = Math.Max(UpperSlider.Value, LowerSlider.Value + oneSecond);
  4.     LowerValue = new DateTime((long)LowerSlider.Value);
  5.     UpperValue = new DateTime((long)UpperSlider.Value);
  6. }

 

So, finally, my 3rd attempt I hit gold.  Why was I setting LowerValue and UpperValue be set by the sliders when I was also setting them in the ValueChanged events?  So I changed my bindings in the sliders to OneWay bindings so I have complete control of the range values and the sliders can suggest was my new UpperValue and LowerValue should be, but I get the final decision in my event handlers.  In my event handlers, I check if the slider values have passed each other and set the dependency properties to appropriate values that make sure that the UpperValue is greater than the LowerValue.

Slider Control Template
  1. private void UpperSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
  2. {
  3.     LowerSlider.Value = Math.Max(Math.Min(UpperSlider.Value - oneSecond, LowerSlider.Value), Minimum.Ticks);
  4.  
  5.     var _upperValue = new DateTime((long)UpperSlider.Value);
  6.     var _lowerValue = new DateTime((long)LowerSlider.Value);
  7.  
  8.     if (UpperValue > _lowerValue)
  9.     {
  10.         LowerValue = _lowerValue;
  11.         UpperValue = _upperValue;
  12.     }
  13.     else
  14.     {
  15.         UpperValue = _upperValue;
  16.         LowerValue = _lowerValue;
  17.     }
  18. }

About these ads
This entry was posted in C#, WPF and tagged , , . Bookmark the permalink.

2 Responses to WPF Date Range Double Slider Control (Part 2)

  1. Pingback: Windows Client Developer Roundup 057 for 1/31/2011 - Pete Brown's 10rem.net

  2. Pingback: Windows Client Developer Roundup 057 for 1/31/2011 · All About Computer

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s