2012-12-13 7 views
6

XAMLには<Slider />があります。 ValueChangedイベントがあります。このイベントは、値が変更されるたびに発生します。私は値の変更が終わったときを検出する必要があります。 LostFocus、PointerReleasedは正しいイベントではありません。これをどのように検出できますか?XAMLスライダが完了したときはどうすれば検出できますか?

+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を使用しました。ユーザーは、スライダーをドラッグし、維持したまま停止した場合、あなたが直接最終的な値が何であるかを検出することはできませんが、私の場合は2回の更新(例えば間に長い休止があるまであなたは、少なくとも操作を遅らせることができ

//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ではない、なぜ3ではない?私は明白な出来事を好むだろうと思う。もし彼らのシステムが遅いのであれば?彼らのシステムが高速ならどうなるでしょうか?私の言っていることが分かるよね。 –

1

ブール値のペア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イベントに触れる必要がありますがキーボード

関連する問題