Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 如何在拖动滑块时停止更新滑块值?_Wpf_Slider - Fatal编程技术网

Wpf 如何在拖动滑块时停止更新滑块值?

Wpf 如何在拖动滑块时停止更新滑块值?,wpf,slider,Wpf,Slider,我发现它的值绑定到某个属性,并且该属性一直在更新它。 在拖动[thumb on]滑块时,我想阻止滑块的此更新值绑定, 直到用户完成它的拖动 Slider上是否有任何属性可以这样做,或者我需要为此编写代码 提前谢谢 滑块的模板包括一个Thumb,它在移动鼠标时引发ThumbDragDelta事件。滑块在收到ThumbDragDelta事件时始终会立即更新绑定值 诀窍是阻止这一事件。最简单的方法是将滑块子类化: public class SliderIgnoreDelta : Slider {

我发现它的值绑定到某个属性,并且该属性一直在更新它。 在拖动[thumb on]滑块时,我想阻止滑块的此更新值绑定, 直到用户完成它的拖动

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);
        }
    }
}