void slider_LowValueChanged(RangeSliderX sender, double oldValue, double newValue)
{
// If we're already dealing with with this problem, allow it to resolve.
// This prevents a cascade of events as every change to a low score causes
// this method to be called
if (resolvingPercentageError) { return; }
// Figure out whether the change puts the "low" sum over 100%
double sum = GetNewSumOfLowRange(sender, newValue);
if (sum <= 100) { return; }
resolvingPercentageError = true;
// Loop through the sliders, reducing each until
// the total amount is less than or equal to 100
while (sum > 100)
{
// We can't do anything with sliders with a zero "low" value, so get
// a list of other sliders that have a non-zero "low" value
List<RangeSliderX> hasLowRangeValue = GetOtherSlidersWithPositiveLowScore(sender);
foreach (RangeSliderX rangeSlider in hasLowRangeValue)
{
// how much more we have to distribute
double amountAboveOneHundred = sum - 100;
// The amount over 100 divided by the number of sliders that have
// a "low" value.
double shareOfAmountOver = Math.Ceiling(amountAboveOneHundred / hasLowRangeValue.Count);
// Try to subtract this amount from the current slider
double remainder = rangeSlider.Low - Math.Ceiling(amountAboveOneHundred / hasLowRangeValue.Count);
// Two possibilities:
// 1) The slider had enough "low" value to subtract its share of the overage
if (remainder > 0)
{
sum -= shareOfAmountOver;
rangeSlider.Low = remainder;
}
else // 2) We could only subtract a part of this slider's share before it became zero
{
// We've reduced this slider's "low" value to zero
rangeSlider.Low = 0;
// The negative remainder represents the amount that we couldn't subtract
// from this slider. Adjust sum to reflect the portion that we subtracted
sum -= (shareOfAmountOver - Math.Abs(remainder));
}
} // for each rangeslider with a low value
} // sum > 100
// The problem has been successfully resolved.
resolvingPercentageError = false;
}