/// <summary> /// After the slider value has changed, update the Value property to /// hold the scaled value. /// </summary> private static void SetValueToTick(SliderMenuItem item, double tickValue) { if (item._tickValueMap.ContainsKey(tickValue)) { item.ItemValue = item._tickValueMap[tickValue]; return; } double[] keys = new double[item._tickValueMap.Keys.Count]; item._tickValueMap.Keys.CopyTo(keys, 0); int index = Array.BinarySearch <double>(keys, tickValue); Debug.Assert(index < 0, "What? How come I didn't find the key already?"); index = ~index; Debug.Assert(index < item.Items.Count, "How did tick value go above 1000?"); Debug.Assert(index != 0, "Insert location was before element 0."); double lowTick = keys[index - 1]; double highTick = keys[index]; double lowValue = item._tickValueMap[lowTick]; double highValue = item._tickValueMap[highTick]; double valueScale = highValue - lowValue; double sourceScale = highTick - lowTick; double newValue = (tickValue - lowTick) * valueScale / sourceScale + lowValue; item.ItemValue = newValue; }
/// <summary> /// Listen for change to Value property. /// </summary> /// <param name="obj"></param> /// <param name="e"></param> private static void Value_ValueChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) { // find appropriate tick spot, and set slider value SliderMenuItem item = obj as SliderMenuItem; if (item != null) { SetTickToValue(item, (double)e.NewValue); } }
/// <summary> /// Sets the slider thumb to the closest match after the value changes. /// </summary> /// <param name="item"></param> /// <param name="newValue"></param> private static void SetTickToValue(SliderMenuItem item, double newValue) { // find tick spot where double[] ticks = new double[item._tickValueMap.Keys.Count]; item._tickValueMap.Keys.CopyTo(ticks, 0); // Find exact match if (item._tickValueMap.ContainsValue(newValue)) { foreach (double tick in item._tickValueMap.Keys) { if (item._tickValueMap[tick] == newValue) { item._slider.Value = tick; return; } } } // Find closest match for (int i = 1; i < item._tickValueMap.Count; i++) { double lowTick = ticks[i - 1]; double highTick = ticks[i]; double lowValue = item._tickValueMap[lowTick]; double highValue = item._tickValueMap[highTick]; //double newValue = (double)e.NewValue; if (newValue > lowValue && newValue < highValue) { double valueScale = highValue - lowValue; double tickScale = highTick - lowTick; // set slider to closest tick match double newTick = (newValue - lowValue) / (valueScale) * tickScale + lowTick; item._slider.Value = newTick; } } }