【发布时间】:2018-12-14 20:29:17
【问题描述】:
我想启用在滚动时按住键盘上的 SHIFT 以水平滚动ScrollViewer。
我从here 了解到PointerWheelChanged 事件是我正在寻找的事件。但是,处理它不起作用,因为ScrollViewer 在内部处理它,所以我的处理程序永远不会被调用。为了解决这个问题,我使用了AddHandler 方法,如"Routed Events Overview" 文章中所述。
这可行...但似乎在ScrollViewer运行其内部代码之后运行我的代码。这样做的结果是ScrollViewer 内容先垂直平移,然后再水平平移。它们似乎按此顺序发生,设置 e.Handled = true 并不能阻止它。
有没有办法“拦截”滚动,所以我可以用自己的逻辑处理它,从而允许ScrollViewer 在按下 SHIFT 时水平平移?我最近问了一个类似的问题(涉及拦截对控件的输入,以便我可以用自己的逻辑处理它)here,答案涉及处理不同的事件,该事件发生在控件运行自己的逻辑之前。对于指针滚动,我没有看到类似的“事前发生”事件。
我的代码如下。请注意,ScrollViewer 可以水平和垂直滚动以及缩放:
<!-- Contained in Grid in a UserControl, if that's relevant -->
<ScrollViewer Name="MyCanvasScrollViewer"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto"
ZoomMode="Enabled"
ZoomSnapPointsType="Optional"
PointerWheelChanged="MyCanvasScrollViewer_PointerWheelChanged">
<!-- Content to pan -->
</ScrollViewer>
代码隐藏:
// Constructor for the user contol.
public MyControl()
{
// Add the scroll wheel event handler and force it to run.
this.MyCanvasScrollViewer.AddHandler(ScrollViewer.PointerWheelChangedEvent, new PointerEventHandler(this.MyCanvasScrollViewer_PointerWheelChanged), true);
// Other un-related stuff omitted here...
}
// Event handler for the Pointer Wheel Changed event.
private void MyCanvasScrollViewer_PointerWheelChanged(object sender, PointerRoutedEventArgs e)
{
// If SHIFT is pressed...
var keyState = CoreWindow.GetForCurrentThread().GetKeyState(VirtualKey.Shift);
if ((keyState & CoreVirtualKeyStates.Down) == CoreVirtualKeyStates.Down)
{
// Get the amount to scroll.
PointerPoint pointer = e.GetCurrentPoint(this.WallCanvasScrollViewer);
double scrollWheelDelta = pointer.Properties.MouseWheelDelta;
// Change the view in the scroll viewer.
this.MyCanvasScrollViewer.ChangeView(scrollWheelDelta, null, null, true);
// Mark event as handled.
e.Handled = true;
}
}
【问题讨论】:
标签: c# xaml uwp event-handling scrollviewer