Проблема
ScrollViewer игнорирует все события KeyDown, для которых OriginalSource не является ScrollViewer.OriginalSource для KeyDown установлен на фокусированный элемент управления, поэтому ScrollViewer игнорирует его, когда у ребенка есть фокус.
Решение
Поймать событие KeyDown и вызватьего копия прямо в ScrollViewer, поэтому он будет иметь правильный OriginalSource, например:
void ScrollViewer_KeyDown(object sender, KeyEventArgs e)
{
if(e.Handled) return;
var temporaryEventArgs =
new KeyEventArgs(e.KeyboardDevice, e.InputSource, e.Timestamp, e.Key)
{
RoutedEvent = e.RoutedEvent
};
// This line avoids it from resulting in a stackoverflowexception
if (sender is ScrollViewer) return;
((ScrollViewer)sender).RaiseEvent(temporaryEventArgs);
e.Handled = temporaryEventArgs.Handled;
}
, обработчик событий может быть добавлен в XAML:
<ScrollViewer KeyDown="ScrollViewer_KeyDown" />
или в коде:
scrollViewer.AddHandler(Keyboard.KeyDownEvent, ScrollViewer_KeyDown);
Последнее более применимо, если ScrollViewer находится где-то внутри шаблона и у вас есть код для его поиска.