2017-02-22 18 views
0

私はWPF Datagridを使用しています。新しい行が追加されたときに自動スクロールさせたいと思います。このため、ItemsSourceのCollectionChangedイベントを追加しても問題ありません。WPF Datagridスクロール

private void dataGrid_Loaded(object sender, RoutedEventArgs e) 
    { 
     var items = (dataGrid.ItemsSource as ObservableCollection<MyViewModel>); 

     if (items == null) 
      return; 

     items.CollectionChanged += MainWindow_CollectionChanged; 
    } 

private void MainWindow_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 
    { 
     if (dataGrid.Items !=null && dataGrid.Items.Count > 0) 
      dataGrid.ScrollIntoView(dataGrid.Items[dataGrid.Items.Count - 1]); 
    } 

問題は、私は、私はデータグリッドのスクロールバーのいずれかをクリックしながら、無効に自動スクロール機能が欲しいです。私はこれを行うことができる方法はありますか?

ありがとうございます!

+0

*のように恒久的に無効*または単にマウスが押されている間? – grek40

+0

スクロールバー上でマウスを押している間は無効にしてから、リリース時に有効な状態に戻します。 – Cosmin

答えて

1

さらに調査したところ、次の簡単な解決策が見つかりました。 Datagridについては、私はスクロールイベントを追加しました。

XAML:

<DataGrid Name="dataGrid" ScrollBar.Scroll ="dataGrid_Scroll"> 
</DataGrid> 

CS:

private void dataGrid_Scroll(object sender, RoutedEventArgs e) 
    { 
     ScrollEventArgs scrollEvent = e as ScrollEventArgs; 
     if (scrollEvent != null) 
     { 
      if (scrollEvent.ScrollEventType == ScrollEventType.EndScroll) 
      { 
       isScrolling = false; 
      } 
      else 
      { 
       isScrolling = true; 
      } 
     } 
    } 
0

添付プロパティを使用して、関連するScrollBarイベントを観察できます。次の例では、イベントリスナーを有効にするためにEnableUserScrollingObserverという2つのプロパティを使用していて、IsUserScrollingは現在のスクロール状態をレポートしています。

public static class Attached 
{ 
    public static bool GetEnableUserScrollingObserver(DependencyObject obj) 
    { 
     return (bool)obj.GetValue(EnableUserScrollingObserverProperty); 
    } 

    public static void SetEnableUserScrollingObserver(DependencyObject obj, bool value) 
    { 
     obj.SetValue(EnableUserScrollingObserverProperty, value); 
    } 

    public static readonly DependencyProperty EnableUserScrollingObserverProperty = 
     DependencyProperty.RegisterAttached("EnableUserScrollingObserver", typeof(bool), typeof(Attached), 
      new FrameworkPropertyMetadata(false, new PropertyChangedCallback(EnableUserScrollingObserverChanged))); 

    private static void EnableUserScrollingObserverChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     var s = d as ScrollBar; 
     if (s != null) 
     { 
      s.Scroll -= Scrollbar_Scroll; 
      if ((bool)e.NewValue) 
      { 
       s.Scroll += Scrollbar_Scroll; 
      } 
     } 
     else 
     { 
      // Using this on anything other than a ScrollBar sucks 
      throw new InvalidOperationException("EnableUserScrollingObserver is designed for ScrollBar elements!"); 
     } 
    } 

    static void Scrollbar_Scroll(object sender, ScrollEventArgs e) 
    { 
     var s = sender as ScrollBar; 
     switch (e.ScrollEventType) 
     { 
      case ScrollEventType.EndScroll: 
       SetIsUserScrolling(s, false); 
       break; 
       /* All the things handled by default 
      case ScrollEventType.First: 
       break; 
      case ScrollEventType.LargeDecrement: 
       break; 
      case ScrollEventType.LargeIncrement: 
       break; 
      case ScrollEventType.Last: 
       break; 
      case ScrollEventType.SmallDecrement: 
       break; 
      case ScrollEventType.SmallIncrement: 
       break; 
      case ScrollEventType.ThumbPosition: 
       break; 
      case ScrollEventType.ThumbTrack: 
       break; 
       */ 
      default: 
       SetIsUserScrolling(s, true); 
       break; 
     } 
    } 



    public static bool GetIsUserScrolling(DependencyObject obj) 
    { 
     return (bool)obj.GetValue(IsUserScrollingProperty); 
    } 

    public static void SetIsUserScrolling(DependencyObject obj, bool value) 
    { 
     obj.SetValue(IsUserScrollingProperty, value); 
    } 

    public static readonly DependencyProperty IsUserScrollingProperty = 
     DependencyProperty.RegisterAttached("IsUserScrolling", typeof(bool), typeof(Attached), 
      new FrameworkPropertyMetadata(false)); 
} 

その後

<Style TargetType="ScrollBar"> 
    <Setter Property="local:Attached.EnableUserScrollingObserver" Value="True"/> 
    <Setter Property="local:Attached.IsUserScrolling" Value="{Binding IsScrolling,Mode=OneWayToSource}"/> 
</Style> 

あなたのviewmodelにIsScrollingプロパティをスクロール情報をつなぐ最後に、あなたのMainWindow_CollectionChanged方法では、IsScrollingプロパティのチェックを追加します。

+0

あなたの答えをありがとう。 ScrollBar.Scrollイベントを使用すると、より簡単な解決策が見つかりました。 – Cosmin

+0

うん、それは 'Scroll'イベントは結局私のソリューションの中核です。私はちょうどそれの周りにコードのblobを構築したので、後ろのコードの代わりにviewmodelで使うことができます:) – grek40