2017-01-02 90 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); 
相關問題