2016-09-29 4 views
0

Ich habe eine Anwendung, wo ich eine bestimmte Aktion ausführen muss, wenn der Benutzer an einen bestimmten Ort in einem ScrollViewer gelangt. Diese Aktion enthält manchmal das Verschieben des ScrollViewer an einem anderen Speicherort programmgesteuert.UWP ScrollViewer - Unterscheiden zwischen Benutzerscrollen und programmgesteuertem Scrollen

Um die Scroll-Aktion des Benutzers zu überwachen, höre ich für die ViewChanged Ereignis der ScrollViewer. Das Problem ist, dass, wenn ich im Ereignis-Handler ViewChanged programrmatisch blättern werde, derselbe Ereignis-Handler wieder aufgerufen wird, wodurch unerwünschtes zusätzliches Scrollen verursacht wird.

Ich habe versucht, eine benutzerdefinierte Methode zu erstellen, um den Ereignishandler vor dem Aufruf ScrollViewer.ChangeView() zu entfernen, aber dies scheint keine Auswirkungen zu haben.

Kann mir jemand einen Weg finden, um dieses Problem zu lösen, oder eine Möglichkeit, die Scroll-Aktion des Benutzers von meiner programmatischen zu unterscheiden?

Antwort

0

Es ist leider nicht möglich festzustellen, was ein ViewChanged Ereignis ausgelöst hat. Es ist jedoch möglich, dieses Problem zu lösen.

Das Problem ist, dass ChangeView() asynchron ist, so wieder den Ereignishandler sofort nach dem Aufruf ChangeView ist zu bald hinzufügen. ChangeView wird eine Reihe von ViewChanged Ereignisse mit einem letzten, wo e.IsIntermediate == false; nur einmal das passiert, sollten Sie den Event-Handler erneut einhängen. Der beste Weg, dies zu umgehen, könnte darin bestehen, einen temporären Event-Handler zu verwenden, der auf diesen e.IsIntermediate == false wartet und dann den ursprünglichen Handler wieder einklinkt.

Um zu verhindern, dass der Benutzer während der Ausführung von ChangeView mit ScrollViewer interagiert, können die Bildlauf- und Zoommodi vorübergehend deaktiviert werden.

Schließlich, wenn der Benutzer die ScrollViewer manipuliert, wenn die Bedingungen erfüllt sind, muss diese Manipulation canceled vor dem Aufruf ScrollTo() sein.

EDIT: In meiner Implementierung entstand ein Problem, wo aufgrund der Häufigkeit, mit der diese Handler aufgerufen wurden, Ereignishandler mehr als einmal hinzugefügt wurden. Um dies zu bekämpfen, habe ich die einfache Strategie von here genommen.

private void MyScrollViewer_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e) 
{ 
    if (!conditionals) return; 

    if (e.IsIntermediate) 
    { 
     var uiElement = MyScrollViewer.Content as UIElement; 
     uiElement?.CancelDirectManipulations(); 
    } 

    ScrollTo(location); 
} 

private void Temporary_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e) 
{ 
    if (e.IsIntermediate) return; 
    MyScrollViewer.ViewChanged -= Temporary_ViewChanged; 
    MyScrollViewer.ViewChanged -= MyScrollViewer_ViewChanged; 
    MyScrollViewer.ViewChanged += MyScrollViewer_ViewChanged; 

    MyScrollViewer.HorizontalScrollMode = ScrollMode.Enabled; 
    MyScrollViewer.VerticalScrollMode = ScrollMode.Enabled; 
    MyScrollViewer.ZoomMode = ZoomMode.Enabled; 
} 

private void ScrollTo(double offset) 
{ 
    MyScrollViewer.ViewChanged -= MyScrollViewer_ViewChanged; 
    MyScrollViewer.ViewChanged -= Temporary_ViewChanged; 
    MyScrollViewer.ViewChanged += Temporary_ViewChanged; 

    MyScrollViewer.HorizontalScrollMode = ScrollMode.Disabled; 
    MyScrollViewer.VerticalScrollMode = ScrollMode.Disabled; 
    MyScrollViewer.ZoomMode = ZoomMode.Disabled; 

    MyScrollViewer.ChangeView(offset, null, null); 
} 
Verwandte Themen