Я создаю слайдер, который сохраняет соотношение текущего значения при изменении максимального или минимального значения.Правильное соотношение значения ползунка при изменении границы
Вот изображение, показывающее, как я корректирую соотношение стоимости на слайдере.
(Второй слайдер расширяется, чтобы лучше объяснить решение. Очевидно, что размер ползунка в виде приложения является фиксированной и только значения внутренне изменились.)
Это то, что вы видите в результате.
Формула я использую, чтобы установить соотношение довольно просто. Это формула используется при изменении Maximum
значение:
NewValue = OldValue * ((newMaximum - Minimum)/(oldMaximum - Minimum));
И в случае Minimum
Значение изменяется:.
NewValue = OldValue * ((Maximum - newMinimum)/(Maximum - oldMinimum));
(есть несколько вещей, чтобы рассмотреть, например, предотвращая деление на ноль, но это вне темы.)
Теперь посмотрим, когда возникнет проблема. Предположим, что newMaximum
меньше значения ползунка. К сожалению, Ползунок внутреннего поведения хочет исправить значение, выполнив value = newMaximum
, и поэтому это противоречит моим вычислениям.
На следующем изображении показана проблема, обратная. Второй слайдер - это то, что я хочу, но получаю третий слайдер.
Это то, что я пробовал. (Код упрощен)
protected override void OnMaximumChanged(double oldMaximum, double newMaximum)
{
if ((oldMaximum - Minimum) <= 0) oldMaximum = Minimum + 1; // prevent 0-division
Value *= (newMaximum - Minimum)/(oldMaximum - Minimum);
base.OnMaximumChanged(oldMaximum, newMaximum);
}
protected override void OnValueChanged(double oldValue, double newValue)
{
//base.OnValueChanged(oldValue, newValue);
}
Даже если я переопределение OnValueChanged
но слайдер продолжает коррекции значения, когда newMaximum
меньше value
делая value = newMaximum
, как вы можете видеть на изображении. Как это исправить?
Внимание: следующий код может дать вам головную боль! Я попытался объяснить проблему, и надеюсь, вы понимаете. в случае, если вы хотите узнать больше информации, здесь полный код OnMaximumChanged
, который у меня есть.
private bool _selfChanging;
protected override void OnMaximumChanged(double oldMaximum, double newMaximum)
{
lock (this)
{
if (_selfChanging) return;
_selfChanging = true;
if (newMaximum < Minimum)
{
IsDirectionReversed = !IsDirectionReversed;
Maximum = Minimum;
newMaximum = Maximum;
Minimum = newMaximum;
}
if ((oldMaximum - Minimum) <= 0) oldMaximum = Minimum + 1;
Value *= (newMaximum - Minimum)/(oldMaximum - Minimum);
base.OnMaximumChanged(oldMaximum, newMaximum);
_selfChanging = false;
}
}
protected override void OnValueChanged(double oldValue, double newValue)
{
//base.OnValueChanged(oldValue, newValue);
}