WPF-如何不更新滑块';拖动时的值

本文关键字:拖动 何不 更新 WPF- | 更新日期: 2023-09-27 18:29:44

您可能会说它是"如何在拖动滑块时停止更新滑块值?"?但老实说,2011年的解决方案对我来说不起作用(甚至其他用户对已接受的答案发表了评论),其他答案对我来说也不相关。所以请耐心等待。

这就是我的问题:我有一个滑块绑定到这样的值:

<Slider Name="AudioSlider" Value="{Binding AudioValue}" 
        Grid.Column="1"    Grid.Row="1"    Height="30" 
        SmallChange="1"    Maximum="100" 
        IsSnapToTickEnabled="True"                                      
        IsMoveToPointEnabled="True"/>

这就是价值:

        private double _audioValue;
        public double AudioValue
        {
            get { return _audioValue; }
            set
            {
                if (_audioValue == value)
                    return;
                _audioValue = value;
                SendPacket(cockpitType, (byte)Index.AudioSlider, (byte)_audioValue);
                OnPropertyChanged("AudioValue");
            }
        }

正如你所看到的,每次值改变时,我都会发送一个数据包,当它在拖动时更新值时,它只是在服务器上滥发值,这是必须防止的。

我试图将滑块绑定到一个函数(mouseUp),但无法通过这种方式获得值。

你知道我能做什么吗?

非常感谢。

编辑:

这里的答案是WPF:带有在用户拖动后触发的事件的滑块对我没有帮助,因为它是数据模板内生成的滑块,事件与我无关。

WPF-如何不更新滑块';拖动时的值

如果您使用的是WPF 4.5,您可以只使用

Value="{Binding AudioValue, Delay=500}"

这将限制更改通知。如果用户快速拖动滑块,这将"重置"内部计时器,并将丢弃挂起的通知。当用户停止并且500毫秒的延迟结束时,它将调用您的setter方法一次。

有很多方法可以做到这一点,所以这只是一个建议。您可以在虚拟机中使用Rx及其Throttle方法来完成此操作。这基本上与BindingDelay属性相同。

我有一个问题,只覆盖其他答案中建议的OnThumbDragCompleted方法。这意味着只有通过拖动拇指来操纵Slider时,更改才会传播。例如,如果你点击拇指旁边,你的房产就不会收到通知。基本上,我要说的是,如果使用从Slider派生的解决方案,则必须确保同步ValueFinalValue的值。

我建议创建自己的滑块,继承原始滑块,这将在拖动开始时清除绑定,并在拖动完成后恢复它。这里有一个例子:

public class CustomSlider : Slider
{
    private Binding SupressedBinding { get; set; }
    protected override void OnThumbDragStarted(DragStartedEventArgs e)
    {
        base.OnThumbDragStarted(e);
        var expression = BindingOperations.GetBindingExpression(this, ValueProperty);
        if (expression != null)
        {
            SupressedBinding = expression.ParentBinding;
            //clearing the binding will cause the Value to reset to default,
            //so we'll need to restore it
            var value = Value;
            BindingOperations.ClearBinding(this, ValueProperty);
            SetValue(ValueProperty, value);
        }
    }
    protected override void OnThumbDragCompleted(DragCompletedEventArgs e)
    {
        if (SupressedBinding != null)
        {
            //again, restoring the binding will cause the Value to update to source's
            //value (which is "out of date" by now), so we'll need to restore it
            var value = Value;
            BindingOperations.SetBinding(this, ValueProperty, SupressedBinding);
            SetCurrentValue(ValueProperty, value);
            SupressedBinding = null;
        }
        base.OnThumbDragCompleted(e);
    }
}

创建一个布尔属性,在mousedown上设置为false,在mouseup上设置为true,并且在您的属性中,仅当该属性为true时才发送数据包?

我完全同意Noctis,此外,您可以使用获取Action<bool>的行为,使用该操作和mousedown/mouseup事件可以通知您是否可以发送数据包。此外,您可以处理mouseup上的最终值,将该值传递给viewmodel,更新AudioValue指示符并发送所需的数据包(您需要另一个行为操作,类似于Action<bool, double>,其中如果您可以发送数据包,则使用boolean signalize,double表示AudioValue本身)。

如果需要代码方面的帮助,我很乐意提供帮助。当做