2012-12-13 64 views
6

在XAML中我有<Slider />。它有ValueChanged事件。每次更改Value都会触发此事件。我需要检测价值变化何时结束。 LostFocus,PointerReleased不是正确的事件。我如何检测这个?如何检测XAML Slider何时完成?

+0

也许一个附加到ValueChanged的计时器? –

+0

听起来像你正在努力的是确定你到底想要接收这个事件。我想如果你知道这一点,那么你可能会想出如何发送它。也许一个带有离散值选项的滑块可以让这个更清晰? – mydogisbox

+0

你有没有解决这个问题? – Carlo

回答

7

您可以创建一个新的类,并从滑块继承。从那里开始,您可以查找Thumb控件&监听您想要的事件。

像这样的东西应该工作:

public class SliderValueChangeCompletedEventArgs : RoutedEventArgs 
{ 
    private readonly double _value; 

    public double Value { get { return _value; } } 

    public SliderValueChangeCompletedEventArgs(double value) 
    { 
     _value = value; 
    } 
} 
public delegate void SlideValueChangeCompletedEventHandler(object sender, SliderValueChangeCompletedEventArgs args); 

public class ExtendedSlider : Slider 
{ 
    public event SlideValueChangeCompletedEventHandler ValueChangeCompleted; 
    private bool _dragging = false; 

    protected void OnValueChangeCompleted(double value) 
    { 
     if (ValueChangeCompleted != null) 
     { 
      ValueChangeCompleted(this, new SliderValueChangeCompletedEventArgs(value)); 
     } 
    } 

    protected override void OnApplyTemplate() 
    { 
     base.OnApplyTemplate(); 
     var thumb = base.GetTemplateChild("HorizontalThumb") as Thumb; 
     if (thumb != null) 
     { 
      thumb.DragStarted += ThumbOnDragStarted; 
      thumb.DragCompleted += ThumbOnDragCompleted; 
     } 
     thumb = base.GetTemplateChild("VerticalThumb") as Thumb; 
     if (thumb != null) 
     { 
      thumb.DragStarted += ThumbOnDragStarted; 
      thumb.DragCompleted += ThumbOnDragCompleted; 
     } 
    } 

    private void ThumbOnDragCompleted(object sender, DragCompletedEventArgs e) 
    { 
     _dragging = false; 
     OnValueChangeCompleted(this.Value); 
    } 

    private void ThumbOnDragStarted(object sender, DragStartedEventArgs e) 
    { 
     _dragging = true; 
    } 

    protected override void OnValueChanged(double oldValue, double newValue) 
    { 
     base.OnValueChanged(oldValue, newValue); 
     if (!_dragging) 
     { 
      OnValueChangeCompleted(newValue); 
     } 
    } 
} 
1

我在Windows8/WinRT上使用Slider也有类似的问题。

我的问题如下:我对ValueChanged事件做出了反应,并在每次触发后执行持久操作(对文件异步写入)。并因此陷入并发编辑异常。为了避免这种情况,我使用了一个DispatcherTimer

//Class member 
    private DispatcherTimer myDispatcherTimer = null; 

    private void OnSliderValueChanged(object sender, RangeBaseValueChangedEventArgs e) 
    { 
     //I update my UI right away 
     ... 

     //If the dispatcher is already created, stop it 
     if (myDispatcherTimer!= null) 
      myDispatcherTimer.Stop(); 

     //Overwrite the DispatcherTimer and thus reset the countdown 
     myDispatcherTimer= new DispatcherTimer(); 
     myDispatcherTimer.Tick += (sender, o) => DoSomethingAsync(); 
     myDispatcherTimer.Interval = new TimeSpan(0,0,2); 
     myDispatcherTimer.Start(); 
    } 

    private async void DoSomethingAsync() 
    { 
     await DoThatLongSaveOperation(); 
    } 

不能直接检测最终值是什么,但你至少可以延迟操作,直到有两次更新之间长时间的停顿(例如,在我的情况下,如果用户拖动滑块和停止,同时保持拖动2秒,无论如何都会触发保存操作)。

+0

Ack!一个计时器。 2秒?为什么不是1. 1秒,为什么不是3?我想我宁愿明确的事件。如果他们的系统很慢?如果他们的系统很快?你知道我的意思。 –

1

您可以使用一对bool值isValueChanged和(如果可能,更改值,不用指针 )isPressed;

private void Slider_ValueChanged(object s, RangeBaseValueChangedEventArgs e) { 
    if (!isPressed) { 
     AcceptChanges(); 
    } else { 
     isValueChanged = true; 
    } 
} 

初始化代码:

Window.Current.CoreWindow.PointerPressed += (e, a) => { isPressed = true; }; 

Window.Current.CoreWindow.PointerReleased += (e, a) => { 
    isPressed = false; 
    if (isValueChanged) AcceptChanges(); 
}; 
+0

不确定这将支持键盘。 –

8

XAML,的WinRT,Windows8.1和UWP:

PointerCaptureLost事件应适用于鼠标/触摸
KEYUP事件键盘