你可能会说它是How to stop update value of slider while dragging it?的副本,但老实说,解决方案是从2011年开始的,并没有为我工作(甚至评论了其他用户接受的答案),其他答案是&n #39;与我相关。所以请耐心等待。
这就是我的问题:我有一个滑块绑定到这样的值:
<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: Slider with an event that triggers after a user drags的答案对我没有帮助,因为它在数据模板中生成了滑块,事件与我无关。
答案 0 :(得分:10)
如果您使用的是WPF 4.5,则可以使用
Value="{Binding AudioValue, Delay=500}"
将限制更改通知。 如果用户快速拖动滑块,则会重置&#34;重置&#34;内部计时器,将删除待处理的通知。当用户停止并且500毫秒延迟结束时,它将调用您的setter方法一次。
有很多方法可以做到这一点,所以这只是一个建议。
您可以在VM中使用Rx及其Throttle方法执行此操作。这与Binding
的{{1}}属性基本相同。
我在覆盖其他答案中建议的Delay
方法时遇到问题。这意味着只有在拖动拇指操纵OnThumbDragCompleted
时才会传播更改。例如,如果您单击拇指旁边的某个属性,您的属性就不会得到通知。基本上我所说的是,如果你要使用从Slider
派生的解决方案,你必须确保同步Value
和FinalValue
的值。
答案 1 :(得分:2)
我建议创建自己的滑块继承自原始滑块,这将在拖动开始时清除绑定并在拖动完成后恢复它。这是一个例子:
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);
}
}
答案 2 :(得分:1)
创建一个布尔属性,在mousedown
上设置为false,在mouseup
上设置为true,并且在您的属性中,仅当该属性为true时才发送数据包?
答案 3 :(得分:0)
我完全同意Noctis,此外你可以使用获得Startup
的行为,并且使用该动作和mousedown / mouseup事件可以发出信号,告知你是否可以发送数据包。此外,您可以处理mouseup的最终值,将该值传递给viewmodel,更新AudioValue指示器并发送您需要的数据包(您需要在行为中执行其他操作,如Action<bool>
,其中boolean signalize如果您可以发送packet和double用于AudioValue本身)。
如果需要有关代码的帮助,我很乐意提供帮助。 问候。