2017-01-02 59 views
0

我创建的滑块可以在最大值或最小值发生变化时保持当前值的比例。当边界发生变化时,滑块值的正确比率

下面是显示我如何修正滑块上的数值比率的图片。

enter image description here

(第二游标扩展到更好地解释解。显然,大小滑块在应用视图是固定的,只值在内部改变。)

这就是你所看到的结果是。

enter image description here

我使用以固定比率的公式是非常简单的。这是当Maximum值改变使用的公式:

NewValue = OldValue * ((newMaximum - Minimum)/(oldMaximum - Minimum)); 

而如果Minimum值改为:

NewValue = OldValue * ((Maximum - newMinimum)/(Maximum - oldMinimum)); 

(也有考虑,例如防止被零除几件事情,但是这)

现在看问题出现的时间。假设newMaximum小于滑块的值。 不幸的是滑块内部行为想要通过执行value = newMaximum来纠正该值,因此这与我的计算冲突。

下图显示了相反的问题。第二个滑块是我想要的,但我得到第三个滑块。

enter image description here


这是我已经试过。 (该代码被简化)

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 = newMaximum,你可以在图片中看到比value小。 我该如何解决这个问题?


警告:下面的代码可能会给你头疼!我试图解释这个问题,我希望你能理解。如果你想知道更多的信息,这里是完整的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); 
} 

回答

0

我是能够解决这个使用帮手值。

private double _oldValue; 
protected override void OnValueChanged(double oldValue, double newValue) 
{ 
    _oldValue = oldValue; // store previous values so we can later fix issues 

    base.OnValueChanged(oldValue, newValue); 
} 

而且在计算

// if (newMaximum < Value) // this will never be true because if value is bigger than newMaximum 
          // slider cuts the Value before we reach here. 

if (newMaximum > Value) // in case newMaximum was bigger than value 
         // that means we are safe to use original value 
         // if newMaximum is equal to Value that means 
         // slider has possibly changed the value we should use _oldValue 
    _oldValue = Value; 

Value = _oldValue * (newMaximum - Minimum)/(oldMaximum - Minimum); 

我这样做和滑块保持率。不管我改变最大或最小的速度有多快。结果是正确的。令人惊讶的是,这里没有竞争条件。

当最小边界发生变化时,同样的逻辑也适用于定量配给。

if (newMinimum < Value) 
    _oldValue = Value; 

Value = _oldValue * (Maximum - newMinimum)/(Maximum - oldMinimum); 
相关问题