Wpf 如何在拖动滑块时停止更新滑块值?
我发现它的值绑定到某个属性,并且该属性一直在更新它。 在拖动[thumb on]滑块时,我想阻止滑块的此更新值绑定, 直到用户完成它的拖动 Slider上是否有任何属性可以这样做,或者我需要为此编写代码Wpf 如何在拖动滑块时停止更新滑块值?,wpf,slider,Wpf,Slider,我发现它的值绑定到某个属性,并且该属性一直在更新它。 在拖动[thumb on]滑块时,我想阻止滑块的此更新值绑定, 直到用户完成它的拖动 Slider上是否有任何属性可以这样做,或者我需要为此编写代码 提前谢谢 滑块的模板包括一个Thumb,它在移动鼠标时引发ThumbDragDelta事件。滑块在收到ThumbDragDelta事件时始终会立即更新绑定值 诀窍是阻止这一事件。最简单的方法是将滑块子类化: public class SliderIgnoreDelta : Slider {
提前谢谢 滑块的模板包括一个Thumb,它在移动鼠标时引发ThumbDragDelta事件。滑块在收到ThumbDragDelta事件时始终会立即更新绑定值 诀窍是阻止这一事件。最简单的方法是将滑块子类化:
public class SliderIgnoreDelta : Slider
{
protected override void OnThumbDragDelta(DragDeltaEventArgs e)
{
// Do nothing
}
}
在拇指拖动完成之前,此滑块不会更新值
另一种解决方案是拦截Thumb上的ThumbDragDelta事件。如果您碰巧正在重新模板化滑块,这可能是一个更好的解决方案。例如,如果您已经编写了一个EventBlocker类,该类在给定RouteEvent上设置了Handled true,则可以将其放入模板中:
<Track.Thumb>
<Thumb my:EventBlocker.EventToBlock="{x:Static Thumb.DragDeltaEvent}" />
</Track.Thumb>
但在大多数情况下,您可能希望使用我的第一个解决方案。我也遇到了同样的问题,所以我做了一个简单的滑块扩展,作为下一个最好的解决方案。将两个事件添加到滑块: 手指头 拇指拖动完成
public class SliderWithDraggingEvents : Slider
{
public delegate void ThumbDragStartedHandler(object sender, DragStartedEventArgs e);
public event ThumbDragStartedHandler ThumbDragStarted;
public delegate void ThumbDragCompletedHandler(object sender, DragCompletedEventArgs e);
public event ThumbDragCompletedHandler ThumbDragCompleted;
protected override void OnThumbDragStarted(DragStartedEventArgs e)
{
if (ThumbDragStarted != null) ThumbDragStarted(this, e);
base.OnThumbDragStarted(e);
}
protected override void OnThumbDragCompleted(DragCompletedEventArgs e)
{
if (ThumbDragCompleted != null) ThumbDragCompleted(this, e);
base.OnThumbDragCompleted(e);
}
}
这两个答案对我都不起作用——第一个答案不会滑动,第二个答案在滑动过程中仍然更新了一个界限值(我想这就是问题所要问的)。 最后,我对滑块进行了子分类,以包含第二个绑定值(Value2,因为缺少更好的名称)的依赖项属性,在拖动滑块时,该属性不会得到更新。所有其他值更新都会反映出来,拖动完成后,该值也会更新。 这门课可能有一些漏洞,但就我的目的而言,它似乎工作得很好
public class SliderNoDragUpdates : Slider
{
public static readonly DependencyProperty Value2Property =
DependencyProperty.RegisterAttached(
"Value2",
typeof(double),
typeof(SliderNoDragUpdates),
new FrameworkPropertyMetadata(0D, new PropertyChangedCallback(OnValue2Changed), new CoerceValueCallback(CoerceValue2))
{
BindsTwoWayByDefault = true,
});
private static object CoerceValue2(DependencyObject d, object value)
{
SliderNoDragUpdates c = (SliderNoDragUpdates)d;
double v = (double)value;
if (v < c.Minimum) v = c.Minimum;
if (v > c.Maximum) v = c.Maximum;
return v;
}
private static void OnValue2Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
d.CoerceValue(Value2Property);
}
public double Value2
{
get { return (double)this.GetValue(Value2Property); }
set
{
if (value != Value2)
this.SetValue(Value2Property, value);
if (value != Value)
this.SetValue(ValueProperty, value);
}
}
private bool _dragging = false;
protected override void OnThumbDragStarted(System.Windows.Controls.Primitives.DragStartedEventArgs e)
{
_dragging = true;
base.OnThumbDragStarted(e);
}
protected override void OnThumbDragCompleted(System.Windows.Controls.Primitives.DragCompletedEventArgs e)
{
_dragging = false;
Value2 = Value;
base.OnThumbDragCompleted(e);
}
protected override void OnValueChanged(double oldValue, double newValue)
{
if (!_dragging)
Value2 = Value;
base.OnValueChanged(oldValue, newValue);
}
}
公共类SliderNodeRagUpdates:滑块
{
公共静态只读依赖项属性值2属性=
DependencyProperty.RegisterAttached(
“价值2”,
类型(双),
类型(SliderNodeRagUpdates),
新的FrameworkPropertyMetadata(0D,新的PropertyChangedCallback(OnValue2Changed),新的强制值回调(强制值2))
{
BindsTwoWayByDefault=true,
});
私有静态对象强制值2(DependencyObject d,对象值)
{
SliderNodeRagUpdates c=(SliderNodeRagUpdates)d;
双v=(双)值;
如果(vc.最大值)v=c.最大值;
返回v;
}
私有静态void OnValue2Changed(DependencyObject d、DependencyPropertyChangedEventArgs e)
{
d、 强制价值(Value2Property);
}
公众双重价值2
{
获取{return(double)this.GetValue(Value2Property);}
设置
{
如果(值!=值2)
此.SetValue(Value2Property,value);
如果(值!=值)
此.SetValue(ValueProperty,value);
}
}
private bool\u drawing=false;
受保护的覆盖无效于UMBDRAGSTARTED(System.Windows.Controls.Primitives.DragStartedEventArgs e)
{
_拖动=真;
基部。从基部开始(e);
}
DragCompleted上的受保护覆盖无效(System.Windows.Controls.Primitives.DragCompletedEventArgs e)
{
_拖动=假;
Value2=值;
基数.已完成的(e);
}
受保护的覆盖无效OnValueChanged(双oldValue,双newValue)
{
如果(!\u拖动)
Value2=值;
base.OnValueChanged(旧值、新值);
}
}
要使用它,请实例化SliderNodeRagUpdates来代替普通滑块,并绑定到Value2而不是Value(或者,实际上-绑定到两者,以便您可以在廉价更新字段中看到值更新,同时等待拖动完成,然后再开始昂贵的操作)
您好,这个解决方案适合我。只需重写Slider类并绑定到xaml中的FinalValue
public class ExSlider : Slider
{
public double FinalValue
{
get { return (double)GetValue(FinalValueProperty); }
set { SetValue(FinalValueProperty, value); }
}
public static readonly DependencyProperty FinalValueProperty =
DependencyProperty.Register(
"FinalValue", typeof(double), typeof(ExSlider),
new FrameworkPropertyMetadata(0d,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
protected override void OnThumbDragCompleted(DragCompletedEventArgs e)
{
base.OnThumbDragCompleted(e);
FinalValue = Value;
}
}
添加了一个标志以指示拖动,并且仅在拖动滑块时发送值更改事件
public class CustomSlider:Slider
{
public bool IsDragging { get; protected set; }
protected override void OnThumbDragCompleted(System.Windows.Controls.Primitives.DragCompletedEventArgs e)
{
IsDragging = false;
base.OnThumbDragCompleted(e);
}
protected override void OnThumbDragStarted(System.Windows.Controls.Primitives.DragStartedEventArgs e)
{
IsDragging = true;
base.OnThumbDragStarted(e);
}
protected override void OnValueChanged(double oldValue, double newValue)
{
if (!IsDragging)
{
base.OnValueChanged(oldValue, newValue);
}
}
}
似乎在OnThumbDragDelta上什么都不做会导致滑块无法操作(您无法滑动)。有趣的是,我认为它过去工作得很好。我也尝试了覆盖方法,但遇到了与tofutim相同的问题。不起作用。有一个解决方案我认为这个解决方案缺少的是一个(在我看来至关重要的)部分-如果由于视图模型值的更改而更新了
最终值
,值
将不会更新,滑块的(视觉)状态将不会反映视图模型上的值。换句话说-FinalValue
仅对OneWayToSource
绑定模式有用。他可以为FinalValue
添加PropertyChangedCallback
,并在其中更新值。但功能仍然丢失。如果他单击拇指旁边并在不拖动拇指的情况下更改值,会发生什么情况<代码>值
已更新,但不会更新最终值
。
public class CustomSlider:Slider
{
public bool IsDragging { get; protected set; }
protected override void OnThumbDragCompleted(System.Windows.Controls.Primitives.DragCompletedEventArgs e)
{
IsDragging = false;
base.OnThumbDragCompleted(e);
}
protected override void OnThumbDragStarted(System.Windows.Controls.Primitives.DragStartedEventArgs e)
{
IsDragging = true;
base.OnThumbDragStarted(e);
}
protected override void OnValueChanged(double oldValue, double newValue)
{
if (!IsDragging)
{
base.OnValueChanged(oldValue, newValue);
}
}
}