2012-12-13 15 views
6

In XAML habe ich die <Slider />. Es hat das ValueChanged-Ereignis. Dieses Ereignis wird bei jeder Änderung von Value ausgelöst. Ich muss erkennen, wenn die Wertänderung vorbei ist. LostFocus, PointerReleased sind nicht das richtige Ereignis. Wie kann ich das erkennen?Wie kann ich erkennen, wenn der XAML-Slider abgeschlossen ist?

+0

Vielleicht ein Timer an ValueChanged angeschlossen? –

+0

Es hört sich so an, als ob Sie damit zu kämpfen haben, wann genau Sie dieses Ereignis erhalten möchten. Ich denke, wenn Sie das herausfinden, werden Sie wahrscheinlich herausfinden, wie Sie es senden. Vielleicht würde ein Schieberegler mit diskreten Wertoptionen das deutlicher machen? – mydogisbox

+0

Haben Sie dieses Problem jemals behoben? – Carlo

Antwort

7

Sie können eine neue Klasse erstellen und von Slider erben. Von dort aus können Sie nach dem Thumb-Steuerelement suchen & für die Ereignisse, die Sie möchten.

So etwas sollte funktionieren:

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

Ich hatte ein ähnliches Problem mit einem Slider auf Windows8/WinRT.

Mein Problem war das Folgende: Ich reagierte auf dasEreignis und führte eine lang andauernde Operation (Schreiben asynchron zu einer Datei) nach jedem Auslöser durch. Und damit in eine gleichzeitige Editier-Ausnahme geraten. Um dies zu vermeiden, habe ich eine DispatcherTimer verwendet.

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

Sie können nicht direkt erkennen, was der Endwert ist, aber Sie können den Betrieb zumindest verzögern, bis es eine lange Pause zwischen zwei Updates (zB in meinem Fall, wenn der Benutzer den Schieber zieht und hält unter Beibehaltung Ziehen Sie für 2 Sekunden, der Speichervorgang wird trotzdem ausgelöst).

+0

Ack! Ein Timer. 2 Sekunden? Warum nicht 1. 1 Sekunde, warum nicht 3? Ich denke, ich würde explizite Ereignisse bevorzugen. Was ist, wenn ihr System langsam ist? Was ist, wenn ihr System schnell ist? Du weißt was ich meine. –

1

Sie können Paar Bool-Werte isValueChanged verwenden und (wenn möglich, ändern Sie den Wert ohne Manipulation des Zeigers ) isPressed;

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

Initialisierung Code:

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

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

Nicht sicher, dass dies die Tastatur unterstützt. –

8

XAML, WinRT, Windows8.1 und UWP:

PointerCaptureLost Ereignis sollte für Maus arbeiten/berühren
KeyUp Ereignis für Tastatur

Verwandte Themen