Изменение
int firstVisibleRow = dgvN.HitTest(dgvN.RowTemplate.MinimumHeight,
dgvN.RowHeadersWidth).RowIndex;
до
int firstVisibleRow = dgvN.FirstDisplayedScrollingRowIndex;
(по крайней мере, я думаю, что это поведение, которое вы хотите, исходя из того, как ваш код вел себя при вставке в мой тестовый проект и вашего комментария о том, что "он не всегда попадает в точку")