【问题标题】:How to limit the range of interdependent sliders?如何限制相互依赖的滑块的范围?
【发布时间】:2016-10-28 11:13:13
【问题描述】:

两个滑块用于显示间隔的值。 范围是例如 0 - 100,在滑块的 min 和 max 属性中设置。 我想确保滑块值不能相互传递。间隔较低值的滑块的拇指不得拖过第二个滑块的值,反之亦然。

将第一个滑块的值绑定到另一个滑块的最小/最大值属性之一(反之亦然)会导致第二个滑块的拇指在修改第一个滑块时移动,因为范围正在改变。所以我想保持两个滑块的范围固定。

如何限制拇指移动?

谢谢!

更新:

在我的附加属性中,我订阅了在 OnSliderMoved 中处理的 ValueChanged 事件:

private static void OnSliderMoved(object sender, RoutedPropertyChangedEventArgs<double> args)
{
  double min = GetMin((DependencyObject)sender);
  double max = GetMax((DependencyObject)sender);

  if (sender is Slider)
  {
    var sld = (Slider)sender;

    var currentValue = sld.Value;
    //check if the value has changed at all
    if (Math.Abs(args.NewValue - args.OldValue) < 0)
    {
      args.Handled = true;
      return;
    }

    double val = 0.0;

    var result = ValidationResult.Ok;

    try
    {
        try
        {
          val = Convert.ToDouble(currentValue, CultureInfo.InvariantCulture);
          val = Math.Round(val + 0.0005, 3);
        }
        catch (Exception e)
        {              
          throw;
        }

        result = ExceedsLimits(val, (double)minimum, (double)maximum);
      }          
    catch (OverflowException)
    {
      result = ValidationResult.TooLarge;
    }


    switch (result)
    {
      case ValidationResult.TooLarge:
        // reset the slider value to maximum
        sld.Value = max;
        args.Handled = true;
        break;
      case ValidationResult.TooSmall:
        // reset the slider value to minimum
        sld.Value = min;
        args.Handled = true;
        break;
      case ValidationResult.Ok:
        BindingExpression binding = BindingOperations.GetBindingExpression(sld, RangeBase.ValueProperty);

        if (binding != null)
        {
          binding.UpdateSource();
        }
        break;
    }
  }
}


<Slider x:Name="sldMaxPercent"
        Value="{Binding SomeValue, UpdateSourceTrigger=Explicit, 
        Converter={optimat:DoulbeToPercentForSliderConverter}}"
        Maximum="100"                                                
        Minimum="0" 
        input:InputService.Min="{Binding ElementName=sldMinPercent, Path=Value, UpdateSourceTrigger=PropertyChanged}"
        input:InputService.Max="100"
        IsMoveToPointEnabled="True"
        IsSelectionRangeEnabled="True"
        IsSnapToTickEnabled="True"
        TickFrequency="0.1">

这样,拇指运动就会停止,这正是我想要的。 问题是,如果我继续在被阻止的方向拖动鼠标,绑定会更新,尽管拇指没有朝那个方向移动。

如何中断绑定更新?

【问题讨论】:

  • 移动滑块时,可以检查是否可以进一步移动。只需使用 ValueChanged 事件。
  • 您可能想要使用范围滑块控件,例如这个:mahapps.com/controls/range-slider.html
  • @MacakM:谢谢,这正是我想要的。我最终创建了一个附加属性,该属性使用 OnValueChanged 检查值是否在所需范围内。
  • @Clemens:我想这将是一个更好的解决方案,但在我的应用程序中,滑块需要保持分离

标签: c# wpf binding slider


【解决方案1】:

使用这样的简单视图模型应该会产生预期的行为:

public class ViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private double lowerValue;
    public double LowerValue
    {
        get { return lowerValue; }
        set
        {
            if (value <= upperValue)
            {
                lowerValue = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("LowerValue"));
            }
        }
    }

    private double upperValue;
    public double UpperValue
    {
        get { return upperValue; }
        set
        {
            if (value >= lowerValue)
            {
                upperValue = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("UpperValue"));
            }
        }
    }
}

将两个 Slider 绑定到视图模型的两个属性:

<Slider Maximum="100" Value="{Binding LowerValue}"/>
<Slider Maximum="100" Value="{Binding UpperValue}"/>

【讨论】:

  • 问题是,Min 和 Max 属性位于一个泛型类中,我无法在 T 类型的值之间进行值比较。我的 ViewModel 只提供这些对象的列表。跨度>
猜你喜欢
  • 2017-04-19
  • 1970-01-01
  • 2016-03-23
  • 2013-04-06
  • 2017-05-05
  • 2015-06-20
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多