2016-08-09 3 views
1

私はユニバーサルWindowsアプリケーションでシンプルにListViewを持っています。タッチ対応デバイスとローカルマシンの両方でうまくスクロールします。タッチデバイスでは、スクロールバーのサムをタップしてドラッグすることで、リストをすばやくスクロールすることができます(マウスでスクロールしてスクロールすると同じです)。しかし、私がスクロールバーの親指を選択しようとすると動作しません。親指は選択できません。UWPリストビューのスクロールバーはタッチモードでは選択できません

最初はスクロールサムがちょっと小さかったので、デフォルトスタイルのScrollBarを使って幅を広げてみました。次に、デフォルトのScrollViewerスタイルの他の値を、ScrollingIndicatorModeScrollingIndicatorStatesのように調整して、常にMouseIndicatorを使用し、すべてIsHitTestVisibleTrueであることを確認しました。無駄に。

これを可能にする既定のスタイルには何かがあるようですが、試行錯誤で見つけることができず、MSDNドキュメントのどこにこのスタイリングに対処するように見えません。

これはタッチモードで実行可能ですか?

+0

私は最近、同様の問題を持って、親指が、 "Horizo​​ntalLargeIncrease" repeatButtonだけではなく」doesnのタッチモードで作業します。 –

答えて

0

後世のために、実際には思っていたほど難しくないと判明した作品を投稿したいと思います。

基本的な考え方は、ときに変化する(垂直配向で(選択可能な、ドラッグ可能でThumb、トラックに沿って移動を有する)Slider制御を使用することであるとSliderValueプロパティを同期しますドラッグしてListViewScrollIntoViewメソッドに移動します。SliderThumbがドラッグされているので、ListViewをスクロールすることができます。シームレスでシームレスな操作のためには、逆方向(ListViewが正常にスクロールするときにSliderThumbに移動する)も必要です。私はあなたのためにいくつかのコードサンプルを持っています(すべてがすぐに働くわけではありません)。さらに、SliderのデフォルトのStyleテンプレートを編集して、スクロールバーのように見えるようにします(また、ドラッグするときに現在の値を表示するツールチップを追加することさえできます)。

注:コードビハインドでWinRTXamlToolkitを使用して、VisualTreeを簡単にトラバースしています。背後

コード:

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> 

ビューモデル:

//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

これはタッチモードで実行可能ですか?

AFAIK、これは現在できません。 ScrollBarのスクロールイベントは、コンテンツをスクロールするか、Thumbをマウス入力で移動することによってのみトリガーされます。

これは仕様ですが、リストをすばやくスクロールしたい場合は、短距離で1つのアイテムをすばやくスワイプします。ListViewはスクロールを高速化してから、最後に停止します。 ScrollViewerを含む他のコントロールは、タッチデバイス内のビューポート(内容はScrollViewer)で同じように振る舞い、親指を動かすことはできません。スクロールをスピードアップするには、ビューポートでスワイプジェスチャを実行するだけです。

Windowsのフィードバックツールを使用して開発するために、この新しい機能を追加するようリクエストを送信することをお勧めします。

+0

慣性スクロール(クイックスワイプ)は、大きなリストをトラバースする正確な方法ではありません。大きな名前のリスト(連絡先など)がある場合は、スクロールバーを把握し、アルファベット順にブラウズできるようにするのがはるかに良い体験です(Androidで)。私は要求を提出する。 – koopaking3

+0

Grace Feng、私は実行可能な回避策が含まれている自分自身の答えを受け入れましたが、私はこれに組み込まれた機能がないことを確認してくれてありがとうと言いました。 – koopaking3

+0

@ koopaking3、これを知っておいてよかった:) –

関連する問題