Обнаружение прокрутки так же просто, как
<DataGrid ScrollViewer.ScrollChanged="DataGrid_ScrollChanged" />
Теперь вы должны получить экземпляр ScrollViewer:
void DataGrid_ScrollChanged(object sender, RoutedEventArgs e)
{
var scroll = FindVisualChild<ScrollViewer>((DependencyObject)sender);
...
}
(Не уверен, где находится источник FindVisualChild, но существует множество реализаций, например, здесь )
И тогда вы можете
int firstRow = (int)scroll.VerticalOffset;
int lastRow = (int)scroll.VerticalOffset + (int)scroll.ViewportHeight + 1;