2012-12-13 87 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事件鍵盤