UWP XAML 使用方向键滚动的 ScrollViewer

UWP XAML ScrollViewer scrolling with arrow keys

我在 XAML 和主页中有一个简单的代码:

<Grid>
    <ScrollViewer ZoomMode="Enabled" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
        <Image Source="Assets/skyline.jpg" KeyDown="Image_KeyDown">

        </Image>
    </ScrollViewer>
</Grid>

现在启动程序时,我可以使用触摸板滚动,但不能使用键盘上的箭头键。为什么会这样,我该如何改变这种行为?我问这个问题是因为我有一个更复杂的例子,它可以正常工作(当然,那个例子不仅仅是一个图像)。谢谢!

您可以使用 ScrollViewerChangeView 方法在 Window.Current.CoreWindow.KeyDown 事件处理程序中滚动。

请参考以下代码示例:

<ScrollViewer x:Name="scrollviewer" ZoomMode="Enabled" HorizontalScrollBarVisibility="Auto"  VerticalScrollBarVisibility="Auto">
        <Image Source="Assets/skyline.jpg">
        </Image>
</ScrollViewer>
public MainPage()
{
    this.InitializeComponent();
    Window.Current.CoreWindow.KeyDown += CoreWindow_KeyDown;
}
private double horizontalOffset;
private double verticalOffset;
private double step = 5;
private void CoreWindow_KeyDown(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.KeyEventArgs args)
{
    Debug.WriteLine("horizontalOffset: "+horizontalOffset+ " verticalOffset: "+verticalOffset);

    switch (args.VirtualKey)
    {

            case Windows.System.VirtualKey.Left: horizontalOffset = horizontalOffset-step<0 ? 0:horizontalOffset - step; scrollviewer.ChangeView(horizontalOffset,verticalOffset,1);  break;
            case Windows.System.VirtualKey.Right: horizontalOffset = horizontalOffset+step>scrollviewer.ScrollableWidth?scrollviewer.ScrollableWidth: horizontalOffset + step; scrollviewer.ChangeView(horizontalOffset,verticalOffset,1);break;
            case Windows.System.VirtualKey.Up: verticalOffset= verticalOffset - step < 0?0:verticalOffset- step; scrollviewer.ChangeView(horizontalOffset,verticalOffset,1);break;
            case Windows.System.VirtualKey.Down: verticalOffset = verticalOffset + step > scrollviewer.ScrollableHeight?scrollviewer.ScrollableHeight:verticalOffset+ step; scrollviewer.ChangeView(horizontalOffset,verticalOffset,1);break;
            default: break;
    }
}

ScrollViewer 响应从其内容冒出的未处理的键盘事件。在您的示例中,您没有看到键盘滚动,因为 ImageScrollViewer 都不可聚焦,这意味着不会有任何键盘事件冒泡到或源自 ScrollViewer . Image 派生自 FrameworkElement 没有焦点的概念。 ScrollViewer 可以 获得焦点。但是,默认情况下,它不会,因为它的默认控件样式有 IsTabStop = "False".

这里简单的解决办法是在ScrollViewer上设置IsTabStop = "True"。现在它是可聚焦的,您将开始在 ScrollViewer 周围看到系统自动绘制的粗焦点矩形。您也可以通过设置 UseSystemFocusVisuals="False" 来禁用它。

在标记中...

<ScrollViewer x:Name="scrollviewer"
              IsTabStop="True" UseSystemFocusVisuals="False"
              ZoomMode="Enabled" HorizontalScrollBarVisibility="Auto"  VerticalScrollBarVisibility="Auto">
    <Image Source="Assets/skyline.jpg">
    </Image>
</ScrollViewer>

注意: 这只是必要的,因为内容中没有任何可以接收焦点的内容。在更复杂的场景中,您通常会在 ScrollViewer 中有一些可以聚焦的东西(例如 'foo' 按钮)。在这些情况下,滚动会如您所料通过键盘输入发生,因为某些 'foo' 具有焦点。