2017-02-22 109 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