2016-04-07 5 views
2

Ich muss die Position des Videos (und auch in einem anderen Fall Dokumentseite) mit einem Schieberegler steuern. Aber das Problem ist, dass ich nicht weiß, wie ich entscheiden soll, ob ein Slider-Wert vom Benutzer geändert wurde (Klick, Daumen ziehen ...), oder ob er von der Bindung stammt. Es ist möglich, ein Ereignis nur auszulösen, wenn der Schiebereglerwert von der Benutzeroberfläche aus aktualisiert wird und nicht vom Binding?WPF Slider - Benachrichtigen, wenn der Wert von UI geändert wurde

Ich habe einen benutzerdefinierten Schieber implementiert:

public class NotifyingSlider : Slider 
{ 

    public static readonly DependencyProperty ValueChangedFromUIProperty = 
     DependencyProperty.Register("ValueChangedFromUI", typeof(ICommand), typeof(NotifyingSlider)); 

    public ICommand ValueChangedFromUI 
    { 
     get 
     { 
      return (ICommand)GetValue(ValueChangedFromUIProperty); 
     } 
     set 
     { 
      SetValue(ValueChangedFromUIProperty, value); 
     } 
    } 

    protected override void OnThumbDragCompleted(DragCompletedEventArgs e) 
    { 
     base.OnThumbDragCompleted(e); 
     ValueChangedFromUI?.Execute(null); 
    } 

    protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e) 
    { 
     base.OnMouseLeftButtonUp(e); 
     ValueChangedFromUI?.Execute(null); 
    } 
} 

Aber ValueChangedFromUI Befehl nur dann ausgeführt wird, wenn der Benutzer per Drag ein Daumen auf die spezifische Position oder klicken Sie auf Balken genau auf die Position der Zecke. Wenn der Benutzer zwischen zwei Häkchen klickt (also Wert/Daumen zum nächsthöheren bewegt wird), wird der Befehl nicht ausgeführt - das ist ein Hauptproblem für mich.

Antwort

2

Leider glaube ich nicht, dass es einen einfachen Weg gibt, dies zu tun. Die Art, wie ich es tun würde ist, den Wert überhaupt nicht zu binden und dem Schieberegler ein ValueChanged-Ereignis hinzuzufügen. Wenn Sie dann etwas tun müssen, wenn der Schieberegler visuell geändert wird, geschieht dies in ValueChanged. Sie möchten auch die Eigenschaft aktualisieren, die den Wert (der nicht gebunden ist) in diesem Ereignis enthält. Auf diese Weise ist der Schiebereglerwert und der Wert, der gebunden werden sollte (ist aber nicht), immer derselbe, und Sie können abhängig davon, was geändert wurde, unterschiedliche Aktionen angeben.

Sie können ein zusätzliches Flag (bool IgnoreUpdate) angeben, das Sie beim Aktualisieren der ungebundenen Eigenschaft auf True setzen können.

Wenn Sie dann die ungebundene Eigenschaft direkt aktualisieren, aktualisieren Sie den Schiebereglerwert mit einer Methode, die IgnoreUpdate überprüft. Wenn IgnoreUpdate wahr ist, versuche nicht, die ungebundene Eigenschaft zu aktualisieren (dies wird zu einer Endlosschleife führen, glaube ich) und setze für die nächste Wertänderung auf false zurück. Wenn es falsch ist, haben wir den Schieberegler visuell geändert und um diese Änderung in der Eigenschaft, die uns interessiert (die ungebundene), widerzuspiegeln, aktualisieren wir sie.

private bool IgnoreUpdate = false; 

private int value = 0; 
public int Value 
{ 
    get 
    { 
     return this.value; 
    } set 
    { 
     this.value = value; 
     this.IgnoreUpdate = true; 
     this.UpdateValue(value); 
    } 
} 

public void UpdateValue(int ProgressValue) 
{ 
    this.Slider.Value = ProgressValue; 
    if (IgnoreUpdate) 
    { 
     IgnoreUpdate = false; 
     return; 
    } 
    //Do stuff when the value changes visually 
    this.Value = ProgressValue; 
} 

private void Slider_ValueChanged(object sender, ProgessChangedEventArgs e) 
{ 
    this.UpdateValue(e.Value); 
} 

nicht sicher, warum Sie es auf diese Weise trotzdem tun wollen würde, aber dies ist die zukunftsorientierten Ansatz, den ich ausdenken konnte.