2016-08-09 6 views
1

Ich habe eine einfache ListView in einer Universal Windows App. Es scrollt sowohl auf einem Gerät mit Touchscreen als auch auf meinem lokalen Computer einwandfrei. Auf dem Touch-Gerät möchte ich in der Lage sein, den Scrollbalken-Daumen zu antippen und zu ziehen, um schnell durch die Liste zu scrollen (so wie Sie den Scroll-Daumen mit der Maus anklicken und ziehen würden). Aber wenn ich versuche, den Rollbalken-Daumen zu wählen, funktioniert es nicht; Der Daumen ist nicht wählbar.UWP ListView Bildlaufleiste nicht im Touch-Modus wählbar

Zuerst dachte ich, der Scroll-Daumen war einfach zu klein, also habe ich mit dem Standard-Stil von ScrollBar fiedled, um die Breite zu erhöhen. Dann habe ich versucht, andere Werte im Standard ScrollViewer Stil, wie ScrollingIndicatorMode und ScrollingIndicatorStates zu optimieren, so dass sie immer MouseIndicator verwenden würden, und sicherstellen, dass alle IsHitTestVisibleTrue sind. Umsonst.

Es scheint, dass es etwas in den Standardstilen geben muss, die dies erlaubt, aber ich kann es nicht durch Versuch und Irrtum finden, und nirgendwo in den MSDN-Dokumenten scheint dieses Styling zu adressieren.

Ist dies im Berührungsmodus möglich?

+0

ich vor kurzem ähnliche Probleme haben, nicht nur die Daumen, sondern die "HorizontalLargeIncrease" Repeat doesn‘ t arbeiten mit Touch-Modus. –

Antwort

0

Um der Nachwelt willen möchte ich meine Arbeiten veröffentlichen, die sich als nicht ganz so schwierig herausstellten, wie ich dachte und jetzt wirklich gut aussieht.

Die Grundidee ist es, eine Slider Steuerung zu verwenden (hat eine Thumb die select-Lage ist, Drag-Lage und bewegt sich entlang einer Schiene) mit einer vertikalen Ausrichtung und der Slider ‚s Value Eigenschaft zu synchronisieren (die sich ändert, wenn geschleppt) auf die ListView ‚s ScrollIntoView Methode, so dass Sie die ListView als die Slider scrollen Thumb gezogen wird. Umgekehrt (verschieben Sie die SliderThumb, wenn die ListView normal scrollt) ist auch für eine saubere, nahtlose Erfahrung erforderlich. Ich habe ein Codebeispiel unten, um Sie zu beginnen (nicht alles ist da, um sofort zu arbeiten). Bearbeiten Sie außerdem die Slider Standardvorlage Style, damit sie genau wie eine Bildlaufleiste aussieht (und sogar eine QuickInfo hinzufügt, um den aktuellen Wert beim Ziehen anzuzeigen).

Hinweis: Ich verwende WinRTXamlToolkit in Code-Behind, um die VisualTree einfach zu durchlaufen.

-Code hinter:

public sealed partial class MainPage : Page 
{ 
    private bool _isScroll = false; 
    private bool _isSlide = false; 

    public MainPage() 
    { 
     this.InitializeComponent(); 
     var vm = new ViewModel(); 
     vm.ValueChanged += LetterSliderValueChanged; 
     DataContext = vm; 
    } 

    /// <summary> 
    /// Bring list items into view on the screen based on the value (letter) of the slider 
    /// </summary> 
    /// <param name="sender">The view model to bring into view</param> 
    private void LetterSliderValueChanged(object sender, RoutedEventArgs e) 
    { 
     if (_isScroll) return; 
     if (sender == null) return; 

     _isSlide = true; 

     ListView?.ScrollIntoView(sender, ScrollIntoViewAlignment.Leading); 
    } 


    /// <summary> 
    /// Update the position of the slider when the ListView is scrolling from a normal touch 
    /// </summary> 
    private void ScrollViewerViewChanged(object sender, ScrollViewerViewChangedEventArgs e) 
    { 
     if (_isSlide) 
     { 
      _isSlide = false; 
      return; 
     } 

     _isScroll = true; 

     var scrollViewer = sender as ScrollViewer; 
     var scrollBars = scrollViewer.GetDescendantsOfType<ScrollBar>(); 
     var verticalBar = scrollBars.FirstOrDefault(x => x.Orientation == Orientation.Vertical); 

     // Normalize the scales to move the slider thumb in sync with scrolling 
     var sliderTotal = LetterSlider.Maximum - LetterSlider.Minimum; 
     var barTotal = verticalBar.Maximum - verticalBar.Minimum; 
     var barPercent = verticalBar.Value/barTotal; 
     LetterSlider.Value = (barPercent * sliderTotal) + LetterSlider.Minimum; 

     _isScroll = false; 
    } 

    /// <summary> 
    /// Add the slider method to the ListView's ScrollViewer Viewchanged event 
    /// </summary> 
    private void ListViewLoaded(object sender, RoutedEventArgs e) 
    { 
     var listview = sender as ListView; 
     if (listview == null) return; 
     var scrollViewer = listview.GetFirstDescendantOfType<ScrollViewer>(); 
     scrollViewer.ViewChanged -= ScrollViewerViewChanged; 
     scrollViewer.ViewChanged += ScrollViewerViewChanged; 
    } 
} 

XAML:

<Slider x:Name="LetterSlider" Orientation="Vertical" 
      Value="{Binding SliderValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
      Maximum="{Binding MaxSliderLetter, Mode=OneTime}" 
      Minimum="{Binding MinSliderLetter, Mode=OneTime}" 
      RenderTransformOrigin="0.5,0.5"> 
     <Slider.RenderTransform> 
      <RotateTransform Angle="180"/> 
     </Slider.RenderTransform> 
</Slider> 

Ansicht Modell:

//Method to update the ListView to show items based on the letter of the slider 
    public RoutedEventHandler ValueChanged; 

    public int SliderValue 
    { 
     get { return _sliderValue; } 
     set 
     { 
      _sliderValue = value; 
      NotifyPropertyChanged("SliderValue"); 

      char letter = (char)_sliderValue; 
      var items = ItemsGroup.FirstOrDefault(i => (char)i.Key == letter); 
      if (items == null) return; 
      ValueChanged(items.FirstOrDefault(), new RoutedEventArgs()); 
     } 
    } 
2

Ist das im Touchbetrieb machbar?

AFAIK, dies ist derzeit nicht möglich. Das Bildlaufereignis von ScrollBar kann nur ausgelöst werden, indem der Inhalt gescrollt oder die Thumb per Mauseingabe bewegt wird.

Dies ist von Entwurf, aber auf dem Touch-Gerät, wenn wir schnell durch die Liste scrollen wollen, wir schnell schnell ein Element für eine kurze Strecke, die ListView wird zunächst das Scrollen beschleunigen und dann verlangsamen und schließlich aufhören . Andere Steuerelemente, die eine ScrollViewer enthalten, verhalten sich im Ansichtsfenster (Inhalt von ScrollViewer), wenn das Touch-Gerät bewegt wird, ist das Bewegen des Daumens nicht möglich, um das Scrollen zu beschleunigen, können Sie nur eine schnelle Wischgeste im Ansichtsfenster geben.

Unser Vorschlag ist, dass Sie eine Anfrage stellen können, um diese neuen Funktionen für die Entwicklung über das Windows-Feedback-Tool hinzuzufügen.

+0

Inertiales Scrollen (Schnellwischen) ist keine genaue Methode zum Durchsuchen einer großen Liste. Wenn Sie eine große Liste von Namen (Kontakte zum Beispiel) haben, ist es eine viel bessere Erfahrung, in der Lage zu sein, die Bildlaufleiste zu erfassen und alphabetisch zu suchen (a la Android). Ich werde eine Anfrage einreichen. – koopaking3

+0

Grace Feng, ich habe meine eigene Antwort akzeptiert, die einen brauchbaren Workaround enthält, aber ich wollte noch einmal Danke sagen, dass es keine eingebaute Funktionalität dafür gibt. – koopaking3

+0

@ koopaking3, gut zu wissen :) –

Verwandte Themen