2012-12-13 13 views
6

W XAML mam <Slider />. Ma wydarzenie ValueChanged. To zdarzenie jest uruchamiane przy każdej zmianie wartości. Muszę wykryć, kiedy zmiana wartości się skończyła. LostFocus, PointerReleased nie są poprawnym wydarzeniem. Jak mogę to wykryć?Jak mogę wykryć, kiedy suwak XAML jest ukończony?

+0

Może zegar dołączony do ValueChanged? –

+0

Wygląda na to, że z czym walczysz, to określenie, kiedy dokładnie chcesz otrzymać to wydarzenie. Myślę, że jeśli to zrozumiesz, najprawdopodobniej dowiesz się, jak to wysłać. Może suwak z dyskretnymi opcjami wartości sprawiłby, że było to bardziej zrozumiałe? – mydogisbox

+0

Czy kiedykolwiek rozwiązałeś ten problem? – Carlo

Odpowiedz

7

Można utworzyć nową klasę i dziedziczą suwak. Od tego momentu możesz poszukać kontrolki Kciuk &, aby posłuchać wybranych wydarzeń.

Coś jak to powinno działać:

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

Miałem podobny problem przy użyciu Slider na Windows8/WinRT.

Mój problem był następujący: Reagowałem na wydarzenie ValueChanged i wykonałem długotrwałą operację (zapisywanie asynchronicznie do pliku) po każdym wyzwalaczu. I w ten sposób uruchamia się współbieżny wyjątek edycji. Aby tego uniknąć, użyłem 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(); 
    } 

Nie można bezpośrednio wykryć co ostateczna wartość, ale można przynajmniej opóźnić operację, dopóki istnieje długa przerwa pomiędzy dwoma aktualizacji (na przykład w moim przypadku, gdy użytkownik przeciąga suwak i zatrzymuje się przy zachowaniu przeciągnij przez 2 sekundy, mimo to operacja zapisu zostanie uruchomiona).

+0

Ack! Timer. 2 sekundy? Dlaczego nie 1. 1 sekunda, dlaczego nie 3? Myślę, że wolałbym wyraźne wydarzenia. Co jeśli ich system działa wolno? Co jeśli ich system działa szybko? Wiesz co mam na myśli. –

1

Można użyć pary wartości bool isValueChanged i (jeśli to możliwe zmienić wartość bez manipulowania wskaźnikiem ) isPressed;

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

kod inicjalizacji:

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

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

Nie jestem pewien, czy to będzie wspierać klawiaturę. –

8

XAML WinRT, Windows8.1 i UWP:

PointerCaptureLost wydarzenie powinno pracować dla myszy/dotknąć
KeyUp wydarzenie dla klawiatura

Powiązane problemy