private void DataGridLoaded(DataGrid dataGrid) { if (VisualTreeHelperEx.FindVisualChildren <ScrollViewer>(dataGrid).FirstOrDefault() is ScrollViewer scrollViewer) { // N.B this doesn't work well if VerticalScrollBar is used to scroll- works for mouse-wheel. if (MouseFactor > 1) { scrollViewer.ScrollChanged += AssociatedObject_ScrollChanged; } scrollViewer .ScrollChanges() .Select(a => ScrollViewerOnScrollChanged(scrollViewer, dataGrid, a)) .Where(a => a.HasValue) .Select(a => a.Value) .ObserveOnDispatcher() .Subscribe(a => { var(firstVisible, lastVisible) = a; FirstIndex = firstVisible; LastIndex = lastVisible; Size = (lastVisible - firstVisible) + 1; }); } void AssociatedObject_ScrollChanged(object sender, ScrollChangedEventArgs e) { if (scrollViewer.VerticalOffset == scrollPosition) { return; } scrollPosition = scrollViewer.VerticalOffset + e.VerticalChange * MouseFactor; if (scrollPosition >= scrollViewer.ScrollableHeight) { scrollViewer.ScrollToBottom(); } else { scrollViewer.ScrollToVerticalOffset(scrollPosition); } }
static (int, int)? ScrollViewerOnScrollChanged(ScrollViewer scrollViewer, DataGrid dataGrid, ScrollChangedEventArgs a) { //AssociatedObject_ScrollChanged(); if (VisualTreeHelperEx.FindVisualChildren <ScrollBar>(scrollViewer).Single(s => s.Orientation == Orientation.Vertical) is ScrollBar verticalScrollBar) { int totalCount = dataGrid.Items.Count; var firstVisible = (verticalScrollBar.Value); var lastVisible = (firstVisible + totalCount - verticalScrollBar.Maximum); return((int)firstVisible, (int)lastVisible); // GetVisibibleItems(firstVisible, lastVisible, dataGrid).ToArray(); } return(null); //static IEnumerable<object> GetVisibibleItems(int firstVisible, int lastVisible, DataGrid dataGrid) //{ // for (int i = firstVisible; i <= lastVisible; i++) // { // yield return dataGrid.Items[i]; // } //} }