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>
现在启动程序时,我可以使用触摸板滚动,但不能使用键盘上的箭头键。为什么会这样,我该如何改变这种行为?我问这个问题是因为我有一个更复杂的例子,它可以正常工作(当然,那个例子不仅仅是一个图像)。谢谢!
您可以使用 ScrollViewer
的 ChangeView
方法在 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
响应从其内容冒出的未处理的键盘事件。在您的示例中,您没有看到键盘滚动,因为 Image
和 ScrollViewer
都不可聚焦,这意味着不会有任何键盘事件冒泡到或源自 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' 具有焦点。
我在 XAML 和主页中有一个简单的代码:
<Grid>
<ScrollViewer ZoomMode="Enabled" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<Image Source="Assets/skyline.jpg" KeyDown="Image_KeyDown">
</Image>
</ScrollViewer>
</Grid>
现在启动程序时,我可以使用触摸板滚动,但不能使用键盘上的箭头键。为什么会这样,我该如何改变这种行为?我问这个问题是因为我有一个更复杂的例子,它可以正常工作(当然,那个例子不仅仅是一个图像)。谢谢!
您可以使用 ScrollViewer
的 ChangeView
方法在 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
响应从其内容冒出的未处理的键盘事件。在您的示例中,您没有看到键盘滚动,因为 Image
和 ScrollViewer
都不可聚焦,这意味着不会有任何键盘事件冒泡到或源自 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' 具有焦点。