2017-02-22 187 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]); 
    } 

問題是我想禁用自動滾屏功能,而我點擊任何Datagrid的滾動條。有什麼辦法可以做到這一點?

謝謝!

+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以便使事件偵聽器和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)); 
} 

然後滾動信息IsScrolling財產

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

最後,連接到您的視圖模型在MainWindow_CollectionChanged方法,添加一個檢查爲IsScrolling財產。

+0

謝謝你的回答。通過使用ScrollBar.Scroll事件,我找到了一個更簡單的解決方案。 – Cosmin

+0

是的,那Scroll事件畢竟是我解決方案的核心。我只是在它周圍構建了一段代碼,所以它可以用於視圖模型而不是代碼背後:) – grek40